文档章节

在Maven+Spring项目中使用Node.js的Gulp进行前端自动化构建

jndion2011
 jndion2011
发布于 2015/04/04 17:30
字数 1953
阅读 5444
收藏 21
点赞 0
评论 3

刚开始打算进行前后端分离开发,后来发现在使用JSP或者Freemarker做动态页面时,想发挥这些自动化构建工具牛逼闪闪的livereload功能并不是那么的轻易,因为我们必须还得调教它们去调用Java容器。现在全球社区似乎还没有成熟的插件可以自动帮我们调教Java容器,百度Fis的Jello也只是做了一下velocity的自动化,自己写感觉就是自虐,所以在这个问题上倒不如把Gulp当成一个Maven来使用,反正J2EE开发人员应该大都习惯了修改代码之后漫长无尽的build。相反,如果对Gulp调教好了watchify,只对发生了修改的文件进行重新构建,那么速度必定不是问题,也不必要我们每次修改都手动打包。

目前刚刚开始应用这一技术,用Gulp主要为了做前端工程和代码优化,之所以没有选择相较而言社区更加健壮的Grunt,可能主要还是因为Gulp的代码写起来更加轻松,而且采用Stream对构建速度有明显的提升。本文使用Gulp主要为了实现以下几个功能:优化CSS,对CSS进行合并,压缩,加MD5版本控制,生成Map映射;优化JS,对JS进行合并,压缩,加MD5版本控制,生成Map映射;优化JSP页面文件,自动产生对应原始文件压缩后资源文件的路径。我们最终要达到的效果是,压缩后的CSS文件一个,压缩后的JS文件一个,JSP页面自动产生对应MD5版本的资源文件。之所以要加MD5进行文件版本控制,是因为MD5在文件未发生修改的情况下,是不会发生改变的,因此服务器相应的资源就不需要进行替换。我们还要考虑到将所有同类资源合并到一个文件内的弊端,那就是如果网站内容较多时,可能大部分资源并不是一个页面真正需要的,这并不是理想的优化效果。对于这个问题,我们可以考虑结合使用browserify等模块管理工具。更省事的方法是,简单分析一下网站对资源的需求。一般的站点通常有一个门户网站和一个后台管理系统,门户网站页面使用到的资源和后台管理系统使用的资源可能会有较大的差异性,而两者自身的页面之间其实差异并不是非常大。所以我们也可以专门为门户网站和后台系统设计两套资源,省去了使用Browserify构建可能产生的大量冗余文件。

使用Gulp之前,我们首先需要安装一下Node.js和NPM包管理工具。因为我们是在Maven+Spring框架下做前端开发,因此在正式写代码之前,还需要搭建好一个maven的项目。一个典型的Maven项目可以如下图所示,在这里我们加了2个maven项目模块,静态资源放在webapp模块中,动态页面放在WEB-INF内,配置完成之后,maven项目就可以正常工作了。

1 类似于maven,npm和gulp也需要相应的配置文件,分别是package.json和gulpfile.js。gulp中我们所需要用到的插件如下:

<!-- lang: js -->
var gulp = require('gulp'),
rev = require('gulp-rev'),
minifycss = require('gulp-minify-css'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'),
sourcemaps = require('gulp-sourcemaps'),
del = require('del'),
revreplace = require('gulp-rev-replace');

使用npm install package-name --save-dev指令可以进行对应插件的安装,或者在配置好package.json文件之后,使用npm install进行一次性安装,所有这些库文件会生成到根目录下的node_module文件夹内。

gulp的工作流程如下:

首先在项目根目录下创建一个src文件夹,将前端需要的静态资源放在文件夹内作为源码开发使用。gulp工作流首先读取这些文件,进行对应的合并压缩处理,最后将产品输出到maven模块相应的静态资源路径和动态页面路径下,这样就完成了一整套简单的自动化构建过程。在下面这个例子中,我们分别构建一个简单的登陆页面和后台页面流程,最后用一个gulp默认指令完成全部工作。首先定义一下文件输入目录:

<!-- lang: js -->
var path = {
    css: 'maven-webapp/webapp/static/css',
    js: 'maven-webapp/webapp/static/js',
    jsp: 'maven-webapp/webapp/WEB-INF/jsp'
};

然后写一个login界面的css压缩合并优化生产线。如下文所示,在这段代码中,我们首先用"del"指令删除上一次构建产生的旧文件。其中rev-manifest.json是MD5版本工具输出的一组数据,它的作用是记录合并后的文件添加了MD5版本数之后的文件名。将4个文件进行合并,合并之前初始化sourcemap,这样在处理完成之后可以生成映射文件,有了这个映射文件,我们就可以在谷歌浏览器的调试工具下面查看到压缩前源码的形式。concat执行文件合并指令,path定义了合并结果的文件名,合并之后用minifycss压缩整理,紧接着给文件加上MD5版本号,到这里修改完成,写出映射文件,并将结果导出到maven项目的目录里面。

<!-- lang: js -->
gulp.task('login-css-min', function() {
del(['rev-manifest.json',
    path.css + '/login.*.*',
    path.js + '/login-bundle.*.*',
    path.jsp + '/login.jsp'], function(err, deletedFiles) {
    console.log('Files deleted:\n', deletedFiles.join('\n'));
});
return gulp.src(['src/css/bootstrap.css',
    'src/css/bootstrap-reset.css',
    'src/css/style-responsive.css',
    'src/css/login.css'])
    .pipe(sourcemaps.init())
    .pipe(concat({path:'login.min.css', cwd: ''}))
    .pipe(minifycss())
    .pipe(rev())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(path.css))
    .pipe(rev.manifest())
    .pipe(gulp.dest(''));
});

js的合并和压缩是类似的。但是需要注意,当我们合并js的时候,还是尽量使用闭包的匿名函数,避免插件污染全局变量。在下面的代码中,我在最头上加了一个namespace.js的文件,将它暴露在全局环境中,目的就是让它做命名空间的管理。

<!-- lang: js -->
gulp.task('login-js-min', ['login-css-min'], function() {
return gulp.src(['src/js/Namespace.js', 'src/js/lib/jquery.js', 'src/js/main.js'])
    .pipe(sourcemaps.init())
    .pipe(concat({path:'login-bundle.min.js', cwd: ''}))
    .pipe(uglify())
    .pipe(rev())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(path.js))
    .pipe(rev.manifest({base:'', merge: true}))
    .pipe(gulp.dest(''));
});

第三步,根据rev-manifest.json的文件名映射,把jsp内对应的资源路径修改成加了MD5版本数字后的路径名。

<!-- lang: js -->
gulp.task("login-build", ['login-js-min'], function() {
var manifest = gulp.src("rev-manifest.json");
return gulp.src( "src/jsp/login.jsp")
    .pipe(revreplace({replaceInExtensions: ['.jsp'], manifest: manifest}))
    .pipe(gulp.dest(path.jsp));
});

同样的方法做一下后台页面的资源合并压缩:

<!-- lang: js -->
gulp.task('index-css-min', function() {
del([
    'rev-manifest.json',
    path.css + '/index.*.*',
    path.js + '/index-bundle.*.*',
    path.jsp + '/index/*.*'], function(err, deletedFiles) {
    console.log('Files deleted:\n', deletedFiles.join('\n'));
});
return gulp.src([
    'src/css/index/jquery.fullPage.css',
    'src/css/index/tipso.min.css',
    'src/css/index/show.css',
    'src/css/index/style.css'
    ])
    .pipe(sourcemaps.init())
    .pipe(concat({path:'index.min.css', cwd: ''}))
    .pipe(minifycss())
    .pipe(rev())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(path.css))
    .pipe(rev.manifest())
    .pipe(gulp.dest(''));
});

gulp.task('index-js-min', ['index-css-min'], function() {
return gulp.src([
    'src/js/Namespace.js',
    'src/js/lib/jquery.js',
    'src/js/lib/jquery.*.min.js',
    'src/js/lib/jquery-ui-1.10.3.min.js',
    'src/js/lib/smooth-scroll.min.js',
    'src/js/lib/tipso.min.js',
    'src/js/lib/transit.js',
    'src/js/index/*.js'])
    .pipe(sourcemaps.init())
    .pipe(concat({path:'index-bundle.min.js', cwd: ''}))
    .pipe(uglify())
    .pipe(rev())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(path.js))
    .pipe(rev.manifest({base:'', merge: true}))
    .pipe(gulp.dest(''));
});

gulp.task("index-build", ['index-css-min','index-js-min'], function() {
var manifest = gulp.src("rev-manifest.json");
return gulp.src( "src/jsp/index/*.jsp")
    .pipe(revreplace({replaceInExtensions: ['.jsp'], manifest: manifest}))
    .pipe(gulp.dest(path.jsp + '/index/'));
});

最后将两个步骤合并到default中去,就完成了自动化。

<!-- lang: js -->
gulp.task('default', ['login-build', 'index-build'], function() {
// place code for your default task here
});

结果如下图所示:

2

3

如果需要让多个jsp页面共用一块资源,可以将这些页面放在一个文件夹中统一进行处理。

© 著作权归作者所有

共有 人打赏支持
jndion2011
粉丝 2
博文 12
码字总数 8228
作品 0
淮南
程序员
加载中

评论(3)

南门吹吹
楼主好棒。。。求项目源码。能发个最好了,453522034@qq.com,谢谢啦
zhaoliuzi
zhaoliuzi
写的非常好。 楼主能否将工程做个demo共享给大家学习?
wkylin
wkylin
我是一名前端开发,对后端了解不是很深,可以提供这个项目的下载么?? 我邮箱地址:wkylin@qq.com 谢谢了
前端自动化构建工具gulp的使用介绍

gulp是基于流的自动化构建工具 简介: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具...

jywud ⋅ 2016/05/14 ⋅ 0

基于Node.js的自动化工具Gulp

基于Node.js的自动化工具Gulp What is gulp? gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用...

笔阁 ⋅ 2015/10/29 ⋅ 1

gulp前端自动化

前言 gulp的运行依赖与node.js,因此需保证node.js已经安装,node.js的下载地址https://nodejs.org/en/ , 以下操作在windows环境下完成,在其他操作系统其实也是相似的 一,安装gulp cmd进入...

上官胡闹 ⋅ 2016/04/30 ⋅ 0

Nodejs 库路径

Gulp.js介绍 Gulp是一个构建系统,开发者可以使用它在网站开发过程中自动执行常见任务。Gulp是基于Node.js构建的,因此Gulp源文件和你用来定义任务的Gulp文件都被写进了JavaScript里。前端开...

雨中人X ⋅ 2015/12/08 ⋅ 0

前端框架汇总

前端框架汇总 一、前端框架库: 1.Zepto.js 地址:http://www.css88.com/doc/zeptojs/ 描述:Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api。 如果你会用...

PXZ6603 ⋅ 2017/04/27 ⋅ 0

基于 Nodejs/Gulp 的前端自动化工具--Flow-CLI

Flow-CLI 是基于 Nodejs/Gulp 的前端自动化工具,是Flow-UI的配套命令行工具,实现自动初始化、组件化开发、静态资源编译、静态资源优化、图片压缩等前端自动化需求。 功能 初始化项目 构建中...

特欧威尔 ⋅ 2017/06/12 ⋅ 0

前端自动化构建工具库之gulp

这是一款基于nodejs的前端自动化构建工具--gulp,以下是使用gulp的步骤: 1.安装主程序,在需要编译的目录输入 2.安装常用插件 3.配置gulpfile.js,如果工作目录下没有该文件,请新建gulpfil...

w-rain ⋅ 2016/05/20 ⋅ 0

前端工程化——构建工具选型

注:文章源于2017年8月的一次内部分享,部分数据可能已经过时。 一、什么是前端工程化 前端工程化是依据业务特点,将前端开发的规范、流程、技术、工具、经验等形成规范并建立成一种标准的体...

Bellhe ⋅ 01/08 ⋅ 0

基于JHipster创建简单Demo【不定时更新中......】

一、JHipster简介 Java 潮客者,Java 极客者 是开源技术 或者 可以称之为工具。 基于 Node.js + Yeoman + Bower + Angular JS + Gulp + Spring Boot 等 Java代码生成器,是各种最佳实践的结合...

涅槃Ls ⋅ 2016/11/22 ⋅ 0

Node.js+Yeoman构建前端自动化Web应用

Yeoman的诞生,旨在为开发者提供一系列健壮的工具、程序库和工作流,帮助他们快速构建出漂亮、引人注目的Web应用。Yeoman主要包含三个部分:yo(脚手架工具)、grunt(构建工具)、bower(包...

大笨牛一只 ⋅ 2015/06/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 1

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

CentOS开机启动subversion

建立自启动脚本: vim /etc/init.d/subversion 输入如下内容: #!/bin/bash## subversion startup script for the server## chkconfig: 2345 90 10# description: start the subve......

随风而飘 ⋅ 昨天 ⋅ 0

Nginx + uwsgi @ubuntu

uwsgi 安装 sudo apt-get install python3-pip # 注意 ubuntu python3默认没有安装pippython3 -m pip install uwsgi 代码(test.py) def application(env, start_response): start_res......

袁祾 ⋅ 昨天 ⋅ 0

版本控制工具

CSV , SVN , GIT ,VSS

颖伙虫 ⋅ 昨天 ⋅ 0

【2018.06.19学习笔记】【linux高级知识 13.1-13.3】

13.1 设置更改root密码 13.2 连接mysql 13.3 mysql常用命令

lgsxp ⋅ 昨天 ⋅ 0

LVM

LVM: 硬盘划分分区成物理卷->物理卷组成卷组->卷组划分逻辑分区。 1.磁盘分区: fdisk /dev/sdb 划分几个主分区 输入t更改每个分区类型为8e(LVM) 使用partprobe生成分区的文件:如/dev/sd...

ZHENG-JY ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部