环境准备
NodeJS安装
在官方网址下载下载安装包即可:https://nodejs.org。
windows环境下只需要step by step,完成后在CMD中输入node -v
查看是否安装成功
npm安装
https://github.com/nodejs-tw/nodejs-wiki-book/blob/master/zh-tw/node_npm.rst
Gulp安装
入门指南:http://www.gulpjs.com.cn/docs/getting-started/
使用Gulp构建项目
说明
在目前的项目中使用Gulp来对前端资源进行构建,在过程当中牵涉到如下几点:
- 文件删除
- RequireJS文件合并。API,需要过一遍原文,因为很多中文翻译内容翻译得不完全
- 文件MD5
- LESS文件编译
- 文件内容中的字符替换。去掉requirejs中config.js里的
.js
后缀 - 文件压缩
- 文件重命名
- Gulp任务顺序处理,解决task异步执行问题
代码样例
var gulp = require('gulp');
var rename = require("gulp-rename"); //- 文件重命名
var concat = require('gulp-concat'); //- 多个文件合并为一个
var rev = require('gulp-rev'); //- 对文件名加MD5后缀
var revCollector = require('gulp-rev-collector'); //- 路径替换
var reqOptimize = require('gulp-requirejs-optimize'); //- requireJs文件合并
var through2 = require('through2'); //- 文件内容操作
var clean = require('gulp-clean'); //- 删除文件
var runSequence = require('run-sequence'); //- 同步执行任务
var less = require('gulp-less'); //- less文件编译
var minifycss = require('gulp-minify-css'); //- css文件压缩
function modify(modifier) {
return through2.obj(function(file, encoding, done) {
var content = modifier(String(file.contents));
file.contents = new Buffer(content);
this.push(file);
done();
});
}
function replaceSuffix(data) {
return data.replace(/\.js/gmi, "");
}
//删除掉上一次构建时创建的资源
gulp.task("clean",function () {
return gulp.src([
'rev-manifest.json',
'**/*-build-*.js',
'**/*-build-*.css',
'static/core/page/login/login.jsp',
'static/core/page/home/home.jsp',
'static/core/page/home/subHome.jsp'
]).pipe(clean());
});
/**
* 首页框架相关资源构建
* 合并了如下资源
* - home-build.js
* - PDCoreDir/corePath
* - PDGlobalDir/base
* - PDHomeDir/js/homeApp
* - PDUtilDir/tabs
* - PDCoreDir/directive
*/
gulp.task("home-build",function (cb) {
gulp.src("static/core/page/home/js/home-build.js")
.pipe(reqOptimize({
//optimize:"none", //- none为不压缩资源
//findNestedDependencies: true, //- 解析嵌套中的require
paths:{
"PDCoreDir":"../../../", //- 相对于home-build.js往上3级
"PDGlobalDir":"../../../../global",
"PDHomeDir":"../",
"PDUtilDir":"../../../../modules/util",
//"PDUtilDir/dialog":"empty:",
"Ace-build":"empty:", //- 指明需忽略的文件
//"jqValidate-build":"empty:",
/*"JQuery.validate":"empty:",
"JQuery.validate.message":"empty:",
"JQuery.validate.extra":"empty:",*/
"Angular":"empty:",
"Angular-ui-router":"empty:",
"PDAppDir/appPath":"empty:",
"PDAppDir/directive":"empty:",
"PDUtilDir/util":"empty:",
"Bootstrap":"empty:",
"jquery":"empty:"
}
}))
.pipe(rev()) //- 文件名加MD5后缀
.pipe(gulp.dest("static/core/page/home/js")) //- 生成MD5后的文件
.pipe(rev.manifest({merge:true})) //- 生成一个rev-manifest.json
.pipe(gulp.dest('')) //- 映射文件输出目录
.on('end', cb);
});
/**
* 首页框架相关资源构建
* 合并了如下资源
* - subHome-build.js
* - PDCoreDir/corePath
* - PDGlobalDir/base
* - PDHomeDir/js/subHomeApp
* - PDCoreDir/directive
*/
gulp.task("subHome-build",function (cb) {
gulp.src("static/core/page/home/js/subHome-build.js")
.pipe(reqOptimize({
//optimize:"none",
//findNestedDependencies: true, //- 解析嵌套中的require
paths:{
"PDCoreDir":"../../../", //相对于home-build.js往上3级
"PDGlobalDir":"../../../../global",
"PDHomeDir":"../",
"PDUtilDir":"../../../../modules/util",
"jqValidate-build":"empty:",
/*"JQuery.validate":"empty:",
"JQuery.validate.message":"empty:",
"JQuery.validate.extra":"empty:",*/
"Angular":"empty:",
"PDAppDir/appPath":"empty:",
"PDAppDir/directive":"empty:",
"PDUtilDir/util":"empty:",
"Bootstrap":"empty:",
"jquery":"empty:"
}
}))
.pipe(rev()) //- 文件名加MD5后缀
.pipe(gulp.dest("static/core/page/home/js")) //- 生成MD5后的文件
.pipe(rev.manifest({merge:true})) //- 生成一个rev-manifest.json
.pipe(gulp.dest('')) //- 映射文件输出目录
.on('end', cb);
});
//ACE文件合并
gulp.task("ace-build",function (cb) {
gulp.src("static/modules/ace/dist/js/ace-build.js")
.pipe(reqOptimize({
//optimize:"none",
//mainConfigFile: 'static/global/config-build.js',
paths:{
"Ace":"ace.min",
"Ace-extra":"ace-extra.min",
"Ace-element":"ace-elements.min",
"Bootstrap":"empty:",
"jquery":"empty:"
},
shim:{
"Ace":["Bootstrap", "jquery"],
"Ace-element":["Ace"],
"Ace-extra":["Ace"]
}
}))
.pipe(rev())
.pipe(gulp.dest('static/modules/ace/dist/js/'))
.pipe(rev.manifest({merge:true}))
.pipe(gulp.dest(''))
.on('end', cb);
});
/**
* jquery.validate.min.js、messages_zh.js、additional-methods.js合并为一个文件
*/
gulp.task("jqValidate-build",function (cb) {
var dir = "static/modules/jquery/plugins/validate";
gulp.src(dir+"/jqValidate-build.js")
.pipe(reqOptimize({
//optimize:"none",
//findNestedDependencies: true,
paths:{
"JQuery.validate":"jquery.validate.min",
"JQuery.validate.message":"localization/messages_zh",
"JQuery.validate.extra":"additional-methods",
"jquery":"empty:"
},
wrapShim:true,
shim:{
"JQuery.validate.message":["JQuery.validate"],
"JQuery.validate.extra":["JQuery.validate"]
}
}))
.pipe(rev())
.pipe(gulp.dest(dir))
.pipe(rev.manifest({merge:true}))
.pipe(gulp.dest(''))
.on('end', cb);
});
//util目录下util.js文件合并压缩
gulp.task("util-build",function (cb) {
gulp.src(['static/modules/util/util-build.js'])
.pipe(reqOptimize({
//optimize:"none",
//findNestedDependencies: true, //- 解析嵌套中的require
paths:{
"PDUtilDir":"",
//"PDUtilDir/dialog":"empty:",
//"Bootstrap":"empty:",
"jquery":"empty:"
}
}))
.pipe(rev()) //- 文件名加MD5后缀
.pipe(gulp.dest("static/modules/util"))
//.pipe(rename({extname: ""})) //- 映射文件中去掉后缀
.pipe(rev.manifest({merge:true})) //- 生成一个rev-manifest.json
.pipe(gulp.dest('')) //- 映射文件输出目录
.on('end', cb);
});
//config文件中路径替换
gulp.task("replaceConfigPathTemp",function (cb) {
gulp.src(['rev-manifest.json', 'static/global/config-build.js'])
.pipe(revCollector())
.pipe(rev())
.pipe(gulp.dest('static/global'))
.pipe(rev.manifest({merge:true}))
.pipe(gulp.dest(''))
.on('end', cb);
});
//替换掉config-build-md5.js文件中的所有js文件后缀
gulp.task("replaceConfigPath",["replaceConfigPathTemp"],function (cb) {
gulp.src(['static/global/config-build-*.js'])
.pipe(modify(replaceSuffix)) //- 去掉.js后缀
.pipe(gulp.dest("static/global"))
//.pipe(rename("config.js")) //- 生成一份不带MD5的config文件
//.pipe(gulp.dest("static/global"))
.on('end', cb);
});
/**
* - 首页路径替换
* - 替换config-build.js、home-build.js
*/
gulp.task("replaceHomePath",function () {
gulp.src(['rev-manifest.json', 'static/core/page/home/home-build.jsp'])
.pipe(revCollector())
.pipe(rename("home.jsp"))
.pipe(gulp.dest('static/core/page/home'));
});
/**
* - SubHome中的路径替换
* - 替换config-build.js、subHome-build.js
*/
gulp.task("replaceSubHomePath",function () {
gulp.src(['rev-manifest.json', 'static/core/page/home/subHome-build.jsp'])
.pipe(revCollector())
.pipe(rename("subHome.jsp"))
.pipe(gulp.dest('static/core/page/home'));
});
gulp.task("replaceLoginFormPath",function () {
gulp.src(['rev-manifest.json', 'static/core/page/login/login-build.jsp'])
.pipe(revCollector())
.pipe(rename("login.jsp"))
.pipe(gulp.dest('static/core/page/login'));
});
//构建总入口
gulp.task('default', function(callback) {
runSequence(
"clean", //- 上一次构建的结果清空
"home-build", //- 首页相关资源合并
"subHome-build", //- SubHome相关
"ace-build", //- ace相关资源合并
"jqValidate-build", //- 语言包与验证插件合并为一个
"util-build", //- 把loading、slidebar合并到util中
"replaceConfigPath", //- config.js中路径处理
//- 需先编译css再替换相关页面路径
"component-less",
"home-less",
"login-less",
//- 可并行处理
["replaceHomePath","replaceSubHomePath","replaceLoginFormPath"],
callback);
});
//文件内容变更动态构建
gulp.task("start", function () {
gulp.watch("static/**",["default"])
});
/***********************LESS文件编译***********************/
/**
* - 登录页面相关
*/
gulp.task("login-less",function (cb) {
var dir = "static/core/page/login/theme";
gulp.src(dir+"/login-build.less")
.pipe(less())
.pipe(minifycss())
.pipe(rev())
.pipe(gulp.dest(dir))
.pipe(rev.manifest({merge:true}))
.pipe(gulp.dest(''))
.on('end', cb);
});
/**
* - util下的所有产品组件
*/
gulp.task("component-less",function (cb) {
var dir = "static/modules/util/css";
gulp.src(dir+"/components-build.less")
.pipe(less())
.pipe(minifycss())
.pipe(rev())
.pipe(gulp.dest(dir))
.pipe(rev.manifest({merge:true}))
.pipe(gulp.dest(''))
.on('end', cb);
});
/**
* - 首页相关
*/
gulp.task("home-less",function (cb) {
var dir = "static/core/page/home/css";
gulp.src(dir+"/home-build.less")
.pipe(less())
.pipe(minifycss())
.pipe(rev())
.pipe(gulp.dest(dir))
.pipe(rev.manifest({merge:true}))
.pipe(gulp.dest(''))
.on('end', cb);
});