使用Gradle整合SpringBoot+Vue.js-开发调试与打包

首先非常感谢kevinz分享的文章《springboot+gradle+vue+webpack 组合使用》,这文章对我的帮助非常大。

我是做Java后台开发的,一般做Java的要做网页都是用jsp,但我并不喜欢在jsp代码中使用jstl标签,我一直想找一个Java能用的前后端分离的解决方案。目前确定比较好的组合是:前台页面用Vue.js,后台用SpringBoot。但是Vue.js在网上能找到的都是需要Node.js环境进行打包的,这使得不懂Node.js的Java程序员望而却步。

在此之前,为了能用上Vue.js快速开发网页,我利用Vue.js的异步组件的特性来加载组件,并配合vue-router来实现组件的视图切换。这样子就能用传统的JavaScript写法在网页端用上Vue.js。对于小型的项目是能适用的,但是对于大型的项目组织起来比较麻烦,而且没有代码压缩、混淆的功能。

在看到kevinz的文章后,我认真研究了,并稍作修改,在这里记下学习的笔记。

我的开发环境如下:

IDE:Intellij IDEA

JDK:Java8

Gradle:3.3

Node.js:6.10.1

Vue-CLI:2.8.1

1.Node.js安装与配置

到官网下载最新的Node.js安装

由于Node.js安装后,默认的node_modules和缓存文件是存在C盘的,最好是修改成其它盘。

在其它盘创建Node.js缓存文件夹,如:

E:\_development\nodejs\global 存放例如用`npm install -g express`命令安装的模块文件E:\_development\nodejs\cache  存放下载缓存

找到【nodejs安装目录】/node_modules/npm/npmrc 文件,用txt打开,修改配置:

prefix=E:\_development\nodejs\global  指定全局安装的node模块的目录

cache=E:\_development\nodejs\cache    指定缓存目录registry=https://registry.npm.taobao.org  指定使用国内的淘宝的Node.js镜像

为了测试配置是否成功,运行一下命令npm install -g express安装一个express试试,Java程序员可能不知道,express是Node.js的后端mvc框架,类似Java中的SpringMVC。如果安装成功,会生成一个E:_developmentnodejsglobalnode_modules目录,express的文件就在该目录下。

新增环境变量:

NODE_PATH=E:\_development\nodejs\global\node_modules

Path环境变量加入路径:

E:\_development\nodejs\global 加入该路径,才能使用后面安装vue-cli后的vue命令

2.vue-cli安装

vue-cli中cli是command line interface的缩写,安装很简单:npm install -g vue-cli,-g是全局安装的意思。安装过程可能比较久。安装完可以通过vue -V查看是否安装成功。如下图:


3.在IDEA搭建项目框架

创建整体工程的结构是,先创建一个总工程,叫show,再创建两个子模块,一个叫server,一个叫web。

打开IDEA,File-->New-->Project-->Gradle-->取消勾选Java-->Next。如下图:


输入父工程的信息,如下图:


设置Gradle相关配置,由于网络特殊原因,最好用本地的Gradle库,配置如下图:


设置项目存放路径,如下图:


项目创建出来就除了Gradle的配置文件,其它什么都没有,接下来要创建两个子工程server和web。show项目创建后如下图:


创建server子项目,对着show项目:

右键-->New-->Module-->Gradle-->勾选Java

-->Next-->ArtifactId填"server"

-->Next-->Finished

创建web子项目,对着show项目:

右键-->New-->Module-->Gradle-->勾选Javaweb

-->Next-->ArtifactId填"web"

-->Next-->Finished

将show总项目的build.gradle文件修改成如下配置:

group 'com.gongshi'

version '1.0'

将show总项目的setting.gradle文件修改成如下配置:

rootProject.name = 'show'

include 'server'

include 'web'

将web子项目的build.gradle文件修改成如下配置:

plugins {

id "com.moowork.node" version "1.1.1"

id 'java'

}

//调用npm run build命令的Gradle任务

task npmBuild(type: NpmTask, dependsOn: npmInstall) {

group = 'node'

args = ['run', 'build']

}

//Gradle的java插件的jar任务,依赖npmBuild,即web子模块打jar包前必须运行npm run build

jar.dependsOn npmBuild

//调用npm run dev

task npmDev(type: NpmTask, dependsOn: npmInstall) {

group = 'node'

args = ['run', 'dev']

}

在上面的代码中,id "com.moowork.node" version "1.1.1"一行是加入了一个Gradle插件,叫gradle-node-plugin,该插件可以通过调用Gradle命令来调用node.js的命令或npm的命令。插件自带了一些内容的命令,如:gradle npmInstall用于运行npm install命名,另外还有:

$ gradle npm_install

$ gradle npm_update

$ gradle npm_list

$ gradle npm_cache_clean

...

将server子项目的build.gradle文件修改成如下配置:

plugins {

id 'org.springframework.boot' version '1.5.2.RELEASE'

id 'java'

}

jar {

baseName = 'server'

version =  '1.0'

}

repositories {

//使用淘宝的maven镜像

maven{ url 'http://maven.aliyun.com/nexus/content/groups/public'}

}

dependencies {

compile project(':web')//server模块依赖web模块

compile("org.springframework.boot:spring-boot-starter-web")

compile("org.springframework.boot:spring-boot-devtools")

testCompile("org.springframework.boot:spring-boot-starter-test")

}

在上面的代码中,需要特别注意的是compile project(':web'),这个设置能在server打包时把web的资源先打包,并作为依赖,加入到server项目生成的jar包中。

13.在IDEA右侧找到Gradle的栏目,点击Refresh All Gradle Projects, IDEA会按找各个build.gradle文件的配置,下载依赖的jar。


到这里为止,项目的结构搭建好了,下一步是先编写一下SpringBoot的代码,把一个简单Java后台跑起来。

4.编写SpringBoot的后台

1.创建包com.gongshi,创建类:Application.java。如下:

package com.gongshi;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.web.servlet.ServletRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.web.context.WebApplicationContext;

import org.springframework.web.servlet.DispatcherServlet;

@SpringBootApplication

public class Application {

private static final Logger logger = LoggerFactory.getLogger(Application.class);

public static void main(String[] args) {

SpringApplication.run(Application.class);

logger.info("SpringBoot server stated on port: 8080");

}

//增加一个SpringMVC的DispatcherServlet,接收前台/api开头的请求

@Bean

public ServletRegistrationBean apiV1ServletBean(WebApplicationContext wac) {

DispatcherServlet servlet = new DispatcherServlet(wac);

ServletRegistrationBean bean = new ServletRegistrationBean(servlet, "/api/*");

bean.setName("ApiServlet");

return bean;

}

}

3.创建包com.gongshi.controller,创建类:AppController.java。如下:

package com.gongshi.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;import java.util.Map;@RestController@RequestMapping("/app")public class AppController { //简单的后台接口,用于测试 @RequestMapping("/info") public Object info(){ Mapmap = new HashMap<>();

map.put("info","hello hello hello");

return map;

}

}

3.在server/src/main/resources目录下,创建一个staic目录,创建一个html页面,用于测试,如下:

index.html


Title

Hello Spring Boot

4.暂时注释掉server/builde.gradle中的compile project(':web')配置(因为web子项目未配置好vue.js相的内容),在IDEA右侧Gradle栏目,点击运行server的bootRun任务,bootRun任务会运行Application.java下的main方法。启动Spring Boot,如下图:


为了测试后台是否正常运行,分别访问一下:

http://localhost:8080,结果如下:


http://localhost:8080/index.html,结果如下:


http://localhost:8080/app/info,结果如下:


以上三个结果中,需要注意下第1个和第2个。Spring Boot默认会将server/src/main/resources/static下的文件作为静态资源,提供给外部访问。当访问http://localhost:8080时,发现static有index.html文件,默认会显示到浏览器端。这就是为什么1和2的结果是一样的。

5.编写Vue.js的前台

在这里前台使用vue-cli生成前台的模板。随便打开一个文件夹,比如:D:demo,按住shift+右键-->在此处打开命令窗口,即可打开一个命令行,输入命令vue init webpack web,其中webpack是用webpack做vue.js的打包工具,web是生成的模板名称。依次做以下的选择:

Project name --> web

Project description --> A Vue.js project

Author --> Hello

Vue build --> 回车

Install vue-router ? --> y

Use ESlint to lint your code? --> n

Setup unit tests with Karma + Mocha? --> n

Setup e2e tests with Nightwatch? --> n

2.执行以上步骤后,vue-cli工具就会将项目模板生成到D:demoweb目录,此时把web目录下所有文件拷贝到IDEA的show/web子项目中。如下图:


3.IDEA下方打开Terminal命令行终端,执行命令:cd web,npm install,这样子npm就会根据package.js中的信息下载依赖的模块。安装后show/web/目录下会出现node_modules目录。如下图:


4.此时需要测试一下vue-cli搭建的web子项目是否正确,打开IDEA右侧Gradle栏目,找到npmDev任务,双击运行一下,任务运行成功会自动打开浏览器,显示localhost:8080,显示Vue的模板页面。如下图:


6.修改Vue.js的前台配置

因为gradle构建输出目录是build,vue-cli生成的模板的构建脚本的目录也是build,因此这里要把构建脚本的build目录修改成script:点选show/web/build目录,shift+F6重命名,将show/web/build目录改成script目录,避免与gradle的构建输出目录冲突。

修改show/web/package.json中与build目录相关的配置:


3.修改show/web/script/webpack.dev.conf.js中与build目录相关的配置:

4.修改show/web/config/index.js中的配置,包括webpack打包输出位置,以及配置代理避免跨域问题,具体修改项看下面注释:

show/web/config/index.js:

// see http://vuejs-templates.github.io/webpack for documentation.

var path = require('path')

var assetsRoot = path.resolve(__dirname, '../build/resources/main/static')// <-----1.add

module.exports = {

build: {

env: require('./prod.env'),

index: path.resolve(assetsRoot, 'index.html'),// <-----2.change

assetsRoot: assetsRoot,// <-----3.change

assetsSubDirectory: 'assets',// <-----4.change

assetsPublicPath: '/',

productionSourceMap: true,

// Gzip off by default as many popular static hosts such as

// Surge or Netlify already gzip all static assets for you.

// Before setting to `true`, make sure to:

// npm install --save-dev compression-webpack-plugin

productionGzip: false,

productionGzipExtensions: ['js', 'css'],

// Run the build command with an extra argument to

// View the bundle analyzer report after build finishes:

// `npm run build --report`

// Set to `true` or `false` to always turn it on or off

bundleAnalyzerReport: process.env.npm_config_report

},

dev: {

env: require('./dev.env'),

port: 3000,// <-----5.change

autoOpenBrowser: true,

assetsSubDirectory: 'assets',// <-----6.change

assetsPublicPath: '/',

proxyTable: {// <-----7.change

'/api/**': 'http://localhost:8080'//代理前台/api开头的请求,代理到8080端口,spring boot的访问端口

},

// CSS Sourcemaps off by default because relative paths are "buggy"

// with this option, according to the CSS-Loader README

// (https://github.com/webpack/css-loader#sourcemaps)

// In our experience, they generally work as expected,

// just be aware of this issue when enabling this option.

cssSourceMap: false

}

}

5.测试show/web子项目的开发环境。关闭spring boot后台,在IDEA右侧Gradle栏目找到npmDev任务并运行。如果运行成功,会自动打开浏览器显示http://localhost:3000,并显示Vue.js的模板页面,此时找到show/web/src/components/Hello.vue,修改一点内容:


exportdefault{  name: 'hello',data() {return{msg: 'WelcometoYourVue.jsApp333333333'//

打开浏览器查看http://localhost:3000,如果对应的内容更新了,则表明web子项目的开发环境正确。

如果运行npmDev报错,有可能是多次运行npmDev命令,有其它Node.js进程占用了端口,打开任务管理器关闭即可,如下图:


5.测试show/web子项目的打包。在IDEA右侧Gradle栏目找到npmBuild任务并运行。如果运行成功,webpack打包的前端资源会输出到show/web/build目录下,如下图:


注意:

我把webpack的打包输出路径故意设置成build/resources/main/static,这样子,web子项目打成jar包后,在classpath中的路径就是/static目录了,即跟spring boot默认的静态资源查找路径是一样的。

再者,server子项目依赖web项目(show/server/build.gradle中的compile project(':web')配置),所以server子项目打jar包前会先将web子项目打成jar包,web子项目的jar包中已经包含了webpack输出的静态资源。

所以,当server子项目打包后,访问http://localhost:8080/index.html就能访问到web子项目webpack打包的输出的index.html文件。

注意:

server子项目打包前,请先删除show/server/src/main/resources/static目录,避免与web子项目打包过来的文件重复。

7.开发调试

先运行show/server子项目的bootRun任务,启动Spring Boot

再运行show/web子项目的npmDev任务,启动node的开发服务器

当show/web子项目有请求需要调用Spring Boot后台,加上/api前缀,请求即可代理从node的开发服务器http://localhost:3000/api/xxxx代理到http://localhost:8080/api/xxxx

而在开发前台页面时候(对show/web/src目录下的文件修改),应该访问http://localhost:3000/,而不是8080端口,访问3000端口,即可看到页面修改的即时效果。

8.打包

运行show/server子项目的build任务,即可完成打包。打包的jar包已经包含show/web子项目的输出内容。




                                                                                     ----文章是复制来的,感谢大牛的分享

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容