Open kuitos opened 9 years ago
原文写于 2014-10-24
对前端构建自动化有所了解的同学应该都听过大名鼎鼎的grunt,但是grunt作为前端自动化构建工具的领头羊现在越来越受到诟病。大而全已经不适应这个时代了,这个时代需要的是小而美的工具及插件。什么都想干往往意味着什么都干不好,YUI的死掉至少说明了近年前端的发展趋势。grunt的不足及弊端大家可以参考这篇文章。后起之秀gulp大有取代grunt的趋势(gulp的github的stars目前已经超过grunt了),本文主要介绍如何通过gulp实现自动化压缩、合并以及文件的修改。 首先来说说我们想要实现的功能吧
<script src=xxx.js?v=0.1></script>
来看看我们怎样通过gulp实现我们的前端工程自动化的吧 首先是一个源码层级的index.html,差不多长这样
<!-- Created by kui.liu on 2014/05/29 14:34. --> <!DOCTYPE html> <html ng-app="invoiceApp"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 一堆css文件。。。。 <!-- build:css css/app.css --> <link href="/src/css/bootstrap-tooltips.css" rel="stylesheet"> <link href="/src/js/lib/jquery-ui/development-bundle/themes/base/jquery.ui.theme.css" rel="stylesheet"> <link href="/src/js/lib/jquery-ui/development-bundle/themes/base/jquery.ui.core.css" rel="stylesheet"> <link href="/src/js/lib/jquery-ui/development-bundle/themes/base/jquery.ui.datepicker.css" rel="stylesheet"> <link href="/src/js/lib/jQuery-Timepicker-Addon/dist/jquery-ui-timepicker-addon.min.css" rel="stylesheet"> <link href="/src/css/float-tips.css" rel="stylesheet"/> <link href="/src/css/ccms.css" rel="stylesheet"> <link href="/src/css/app.css" rel="stylesheet"> <link href="/src/js/lib/ccms_pop/css/style.css" rel="stylesheet"> <!-- endbuild --> <style> [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; } </style> <title>账户管理</title> <script> // 设置资源文件目录,必需!! window.ResourceDir = "/src/"; </script> </head> <body ng-cloak class="ng-cloak" ng-controller="AppCtrl"> 此处省略若干结构。。。 一堆js文件 <!-- build:js js/app.js --> <script src="/src/js/lib/jquery/jquery-1.11.1.js"></script> <script src="/src/js/lib/jquery-ui/development-bundle/ui/jquery.ui.core.js"></script> <script src="/src/js/lib/jquery-ui/development-bundle/ui/jquery.ui.datepicker.js"></script> <script src="/src/js/lib/jQuery-Timepicker-Addon/dist/jquery-ui-timepicker-addon.min.js"></script> <script src="/src/js/lib/jQuery-Timepicker-Addon/dist/i18n/jquery-ui-timepicker-zh-CN.js"></script> <script src="/src/js/lib/bootstrap/bootstrap-tooltips.js"></script> <script src="/src/js/lib/ccms_pop/js/yunat_pop.js"></script> <script src="/src/js/float-tips.js"></script> <script src="/src/js/lib/angular/angular.js"></script> <script src="/src/js/lib/angular/angular-locale_zh-cn.js"></script> ........... <!-- endbuild --> </body> </html>
然后是我们开发时的目录结构 image2014-10-26 15:30:4.png 然后我使用gulp定义了一系列构建任务后,执行一下命令 gulp build (假设你也写了个名为build的任务) 我们的工程变成这样了 首先是工程目录 image2014-10-26 15:32:40.png 然后是/dist/index.html
<!-- Created by kui.liu on 2014/05/29 14:34. --> <!DOCTYPE html> <html ng-app="invoiceApp"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <link rel="stylesheet" href="/dist/css/app-cb402b9f.css"/> <style> [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; } </style> <title>账户管理</title> <script> // 设置资源文件目录,必需!! window.ResourceDir = "/dist/"; </script> </head> <body ng-cloak class="ng-cloak" ng-controller="AppCtrl"> ........ <script src="/dist/js/app-3db90639.js"></script> </body> </html>
可以看到,/dist目录如期而至,而且长得跟我们预想的一样,然后是/dist/index.html,所有的css和js引用均指向一个压缩合并后的文件,眼尖的同学会发现,后面跟的那一串奇怪的数字是啥,如 app-3db90639.js。中划线后面那串数字是我们通过gulp计算了合并文件的MD5之后算出的hash值,也就是说,只要你的源码有改动,那么这个hash值便会自动追加到合并文件后面,而不需要你每次手动修改版本号那种古老的做法,一切都是gulp帮我们做好,我们需要做的就是敲一行命令就好了。赞一个!
下面具体介绍一下gulp怎么玩才能达到上文的效果
安装gulp、bower(假设你有用到)等node组件
node install gulp -g node install gulp --save-dev
引入gulp合并、压缩等插件(package.json文件)
"devDependencies": { "gulp" : ">=3.8.8", "del" : ">=0.1.3", "gulp-minify-css" : ">=0.3.10", "gulp-minify-html": ">=0.1.6", "gulp-replace" : ">=0.4.0", "gulp-rev" : ">=1.1.0", "gulp-uglify" : ">=1.0.1", "gulp-usemin" : ">=0.3.8", "run-sequence" : ">=1.0.1" }
构建gulp任务流,就像这样
/** * @author kui.liu * @since 2014/09/29 上午11:45 */ "use strict"; var webRoot = "src/main/webapp/", gulp = require('gulp'), del = require('del'), runSequence = require('run-sequence'), minifyCss = require('gulp-minify-css'), minifyHtml = require('gulp-minify-html'), uglify = require('gulp-uglify'), rev = require('gulp-rev'), replace = require('gulp-replace'), usemin = require('gulp-usemin'); /*------------------------- 清空dist目录 -----------------------------*/ gulp.task('clean', function (cb) { del(webRoot + "dist/*", cb); }); /*------------------------- 拷贝资源文件 -----------------------------*/ gulp.task('copy-tpl', function () { return gulp.src(webRoot + 'src/tpls/**/*.html') // .pipe(minifyHtml({empty: true, quotes: true})) .pipe(gulp.dest(webRoot + 'dist/tpls')); }); gulp.task('copy-font', function () { return gulp.src(webRoot + 'src/fonts/*') .pipe(gulp.dest(webRoot + 'dist/fonts/')); }); gulp.task('copy-image', function () { return gulp.src(webRoot + 'src/images/**/*') .pipe(gulp.dest(webRoot + 'dist/images')); }); gulp.task('copy-jqueryui-image', function () { return gulp.src(webRoot + 'src/js/lib/jquery-ui/development-bundle/themes/base/images/*') .pipe(gulp.dest(webRoot + 'dist/css/images')); }); /*------------------------- 对首页引用的css、js作合并压缩,并根据文件md5值自动更新 -----------------------------*/ /*------------------------- 首页html需要加入build标识,具体参照gulp-usemin插件文档 -----------------------------*/ gulp.task('usemin', function () { return gulp.src(webRoot + 'src/index.html') .pipe(replace(/\/src\/(js|css)/g, '$1')) .pipe(usemin({ css: [minifyCss({keepSpecialComments: 0}), rev()], // html: [minifyHtml({empty: true, quotes: true})], js : [uglify(), rev()] })) .pipe(replace(/(js\/|css\/)/g, "/dist/$1")) .pipe(replace(/\/src\//g, "/dist/")) .pipe(gulp.dest(webRoot + 'dist/')); }); // 定义构建任务队列 gulp.task('build', function (cb) { runSequence('clean', ['copy-tpl', 'copy-font', 'copy-image', 'copy-ccmsPop-image', 'copy-jqueryui-image', 'usemin'], cb); });
gulp采用管道流机制定义任务,任务的定义跟使用变得更易用和清晰。要运行单个定义的任务很简单,比如上面定义的clean任务:
gulp clean
一般情况下我们不会只执行一个构建任务,如果要一个个任务去敲命令显然是效率低下的,这里引入runSequence插件,从而自定义任务队列,比如上面我们定义build任务用来执行所有的合并、压缩的任务,执行方式跟其他任务一样:
gulp build
有的时候我们还用了bower等其他工具,不仅仅是gulp。那么构建工程的时候需要bower install,然后gulp build。懒人总想找到更简单的方式,我们在package.json中加入这个
"scripts" : { "start": "npm install & bower install --allow-root & gulp build" }
这样我们构建项目只需要一个命令就OK
npm start
命令跑完之后一切就都变成了你想要的模样。就是这么简单。so easy!麻麻再也不用担心我每次发布都要小心翼翼了。
ps:由于我们node配置文件是放在项目根路径下的,而maven只打包webapp下的资源,所以如果你不想每次发布前还要手动跑node命令然后提交编译目录,配合bamboo可以在maven打包前加上脚本命令,如图 image2014-10-27 10:7:27.png
更多详细代码请移步:source code
前端工程之构建工具-gulp实战
原文写于 2014-10-24
对前端构建自动化有所了解的同学应该都听过大名鼎鼎的grunt,但是grunt作为前端自动化构建工具的领头羊现在越来越受到诟病。大而全已经不适应这个时代了,这个时代需要的是小而美的工具及插件。什么都想干往往意味着什么都干不好,YUI的死掉至少说明了近年前端的发展趋势。grunt的不足及弊端大家可以参考这篇文章。后起之秀gulp大有取代grunt的趋势(gulp的github的stars目前已经超过grunt了),本文主要介绍如何通过gulp实现自动化压缩、合并以及文件的修改。 首先来说说我们想要实现的功能吧
<script src=xxx.js?v=0.1></script>
。这样太麻烦。合理的应该是,只要我们的源码有改动,那么我们引用的资源版本号就应该自动更新。来看看我们怎样通过gulp实现我们的前端工程自动化的吧 首先是一个源码层级的index.html,差不多长这样
然后是我们开发时的目录结构
image2014-10-26 15:30:4.png
然后我使用gulp定义了一系列构建任务后,执行一下命令 gulp build (假设你也写了个名为build的任务)
我们的工程变成这样了
首先是工程目录
image2014-10-26 15:32:40.png
然后是/dist/index.html
可以看到,/dist目录如期而至,而且长得跟我们预想的一样,然后是/dist/index.html,所有的css和js引用均指向一个压缩合并后的文件,眼尖的同学会发现,后面跟的那一串奇怪的数字是啥,如 app-3db90639.js。中划线后面那串数字是我们通过gulp计算了合并文件的MD5之后算出的hash值,也就是说,只要你的源码有改动,那么这个hash值便会自动追加到合并文件后面,而不需要你每次手动修改版本号那种古老的做法,一切都是gulp帮我们做好,我们需要做的就是敲一行命令就好了。赞一个!
下面具体介绍一下gulp怎么玩才能达到上文的效果
安装gulp、bower(假设你有用到)等node组件
引入gulp合并、压缩等插件(package.json文件)
构建gulp任务流,就像这样
gulp采用管道流机制定义任务,任务的定义跟使用变得更易用和清晰。要运行单个定义的任务很简单,比如上面定义的clean任务:
一般情况下我们不会只执行一个构建任务,如果要一个个任务去敲命令显然是效率低下的,这里引入runSequence插件,从而自定义任务队列,比如上面我们定义build任务用来执行所有的合并、压缩的任务,执行方式跟其他任务一样:
有的时候我们还用了bower等其他工具,不仅仅是gulp。那么构建工程的时候需要bower install,然后gulp build。懒人总想找到更简单的方式,我们在package.json中加入这个
这样我们构建项目只需要一个命令就OK
命令跑完之后一切就都变成了你想要的模样。就是这么简单。so easy!麻麻再也不用担心我每次发布都要小心翼翼了。
ps:由于我们node配置文件是放在项目根路径下的,而maven只打包webapp下的资源,所以如果你不想每次发布前还要手动跑node命令然后提交编译目录,配合bamboo可以在maven打包前加上脚本命令,如图
image2014-10-27 10:7:27.png
更多详细代码请移步:source code