我们的官网要改版,会从以前的单一产品变成系列产品的官网,也就是现在的官网会是之后官网的一个子模块。
趁着这个机会,正好重新梳理了一下结构。加上罪恶之主管的一些要求,具体的需求如下:
分模块,每个模块都有独立的页面和静态文件,并将所有静态文件打在一个文件夹下,
一些常用变量可以进行替换,并可进行简单的页面动态生成,
生产环境打包与线上环境打包分开进行,
静态文件进行压缩合并,加md5以及cdn,
wap的静态文件与web端分离,wap的页面文件没有的继承web端的页面文件,有的要用它本身。
打包由grunt换成gulp。
整体的路径要像这样:
好了,那我们开始,首先当然是要安装gulp
npm install gulp --save-dev
然后你需要在你的环境里加一个gulpfile.js的文件。
然后我们为了高大上一点,给弄个简易的手册出来:
直接console.log输出就好了···
- // 说明
-
-
gulp.task('help',function(){
-
-
console.log(' gulp build 文件打包');
-
-
console.log(' gulp watch 文件监控打包');
-
-
console.log(' gulp help gulp参数说明');
-
-
console.log(' gulp server 测试server');
-
-
console.log(' gulp -p 生产环境(默认生产环境)');
-
-
console.log(' gulp -d 开发环境');
-
-
console.log(' gulp -m <module> 部分模块打包(默认全部打包)');
-
- });
-
- /* 默认 */
-
-
gulp.task('default',function(){
-
-
gulp.start('help');
-
- });
然后在你的控制台输入 gulp help或者 gulp build 就可以看到效果啦
然后我们要建立我们的build任务啦~
首先我们需要接收参数判断是开发打包还是生产打包。这里需要一个插件-- yargs,以及我们以后需要用到的工具类的插件:lodash(用于操作数组,当然它不仅仅是有这样的用处)和 path(用于写路径),用npm像上面那样加到你的环境中,
并且在你的gulpfile文件中声明它们:
- /* 载入工具 */
-
-
var argv =require('yargs').argv,
-
-
_ =require('lodash'),
-
-
path =require('path');
记得之后载入的插件都需要这样声明。
我们新建一个叫build的task
//创建任务
-
gulp.task('build',function(){
-
-
-
- });
在里面获取一下控制台输入的参数:
var evr = argv.p || !argv.d; //生产环境为true,开发环境为false,默认为true
var mod = argv.m || 'all';//模块明,默认为全部
这样你在控制台输入 gulp build -p 或者 gulp build -p -m t1这样就可以在里面获得参数啦。
然后我们需要进行一些打包的配置,先在写一个叫FileConfig的js文件,在里面写我们需要的文件配置信息:
-
"use strict";
-
-
var path =require('path');
-
- /* 环境信息 */
-
-
var source ='source',
-
-
develop ='develop',
-
-
production ='production';
-
-
-
- /* src路径 */
-
-
var src ={
-
-
tpl:'tpl/**',
-
-
css:'styles/**/*.less',
-
-
js:'lib/**/*.js',
-
-
html:'/**.html',
-
-
img:'images/**'
-
- }
-
- /* 模块信息 */
-
-
var modules ={
-
-
"t1":{
-
-
src:'t1',
-
-
dest:'t1',
-
-
name:'t1',
-
-
css_files:'styles/app.less'
-
- },
-
-
"t2":{
-
-
src:'t2',
-
-
dest:'t2',
-
-
name:'t2'
-
- },
-
-
"index":{
-
-
src:'index',
-
-
dest:'index',
-
-
name:'index'
-
- },
-
-
"common":{
-
-
src:'common',
-
-
dest:'common',
-
-
name:'common'
-
- }
-
- };
然后在下面写个方法:
var FileConfig = function () {
};
为了省事儿,直接在exports的时候就new了它···
module.exports = new FileConfig();
之后我们的一些配置信息全部从FileConfig这个方法里取,比如要模块信息的话:
FileConfig.prototype.modules = function () {
return modules;
};
之后的具体实现就不再啰嗦啦。
然后我们回到gulpfile.js文件下,声明他,之后会用到。
然后我们就要对html,css,js,img进行处理啦,这里会用到很多插件,一次性的列举出来,用法我在后面的注释中写了:
- // 载入外挂
-
-
var gulp =require('gulp'),
-
-
browserify =require('browserify'),//这里用不上,管理js依赖的
-
-
source =require('vinyl-source-stream'),//同样这里用不上,和上面那个一起的
-
-
uglify =require('gulp-uglify'),//混淆js
-
-
clean =require('gulp-clean'),//清理文件
-
-
notify =require('gulp-notify'),//加控制台文字描述用的
-
-
buffer =require('vinyl-buffer'),
-
-
less =require('gulp-less'),//转换less用的
-
-
autoprefixer =require('gulp-autoprefixer'),//增加私有变量前缀
-
-
minifycss =require('gulp-minify-css'),//压缩
-
-
concat =require('gulp-concat'),//合并
-
-
fileinclude =require('gulp-file-include'),// include 文件用
-
-
template=require('gulp-template'),//替换变量以及动态html用
-
-
rename =require('gulp-rename'),//重命名
-
-
webserver =require('gulp-webserver'),//一个简单的server,用python的SimpleHttpServer会锁文件夹
-
-
imagemin =require('gulp-imagemin'),//图片压缩
-
-
gulpif =require('gulp-if'),//if判断,用来区别生产环境还是开发环境的
-
-
rev =require('gulp-rev'),//加MD5后缀
-
-
revReplace =require('gulp-rev-replace'),//替换引用的加了md5后缀的文件名,修改过,用来加cdn前缀
-
-
addsrc =require('gulp-add-src'),//pipeline中途添加文件夹,这里没有用到
-
-
del=require('del'),//也是个删除···
-
-
vinylPaths =require('vinyl-paths'),//操作pipe中文件路径的,加md5的时候用到了
-
-
runSequence =require('run-sequence');//控制task顺序
好啦,为了省事儿,写个对象字面量的方法集:
- /* 打包方法 */
-
-
var teemoGulp ={
-
- /* html打包 */
-
-
buildHtml :function(){},
-
- /* css 打包 */
-
-
buildCss :function(){},
-
- /* js打包 */
-
-
buildJs :function(){},
-
- /* img打包 */
-
-
buildImg:function(){},
-
- /* md5打包 */
-
-
buildMd5:function(){}
-
- }
然后我们先说简单的,js打包,只需要初始路径和打包后路径就好啦:
- /* js打包 */
-
-
buildJs :function(){
-
-
var src = arguments[0],dest = arguments[1], flag = arguments[2]
-
-
return gulp.src(src)
-
-
.pipe(gulp.dest(dest))
-
-
-
-
.pipe(uglify())
-
-
.pipe(rename({ suffix:'.min'}))
-
-
.pipe(gulp.dest(dest));
-
- }
其中flag是之前的这个var evr = argv.p || !argv.d; //生产环境为true,开发环境为false,默认为true,这个比较简单,先把原始文件拷贝一份,在混淆压缩加.min后缀存一份。
img打包也很简单
- /* img打包 */
-
-
buildImg:function(){
-
-
var src = arguments[0],dest = arguments[1], flag = arguments[2]
-
-
return gulp.src(src)
-
-
.pipe(gulpif(flag, imagemin()))
-
-
.pipe(gulp.dest(dest));
-
- },
这里注意一下用到了 gulpif 根据环境来判定是否需要做 图片的压缩操作,因为这项操作比较费时间,开发环境下就不进行了。
css打包和html打包需要用到一些存好的变量,比如,如果我们需要每个页面的keywords是一样的:
<meta name="keywords" content="<%- keywords %>">
我们就需要给这些变量一个配置的地方,这个和fileconfig是一样的,就不再说了。然后替换这些变量我们要用到 gulp-template,他继承了lodash的template的用法,也就是说,他可以识别js代码以及lodash的一些用法。
而当我们想增加一些文件时,就要用到gulp-file-include,或者你直接改lodash,让他支持html代码也可以,不过我不赞成这样做。
他的用法类似这样:
@@include('t1/tpl/menu.html')
整体的html打包代码是这样:
- /* html打包 */
-
-
buildHtml :function(){
-
-
var src = arguments[0],dest = arguments[1], flag = arguments[2], options = arguments[3];
-
-
return gulp.src(src)
-
-
.pipe(fileinclude({
-
-
basepath:basePath.source
-
- }))
-
-
.pipe(template(options,{
-
- //interpolate: /\{-([\s\S]+?)-\}/g
-
- }))
-
-
.pipe(gulp.dest(dest))
-
- },
template默认的包裹变量的标示是 <%-%>当然你可以用 interpolate去配置这些。
好啦,方法我们写好了,下面是引用他们,我们需要在写一个方法,
-
var build = funciton (){
-
- }
然后获取参数信息,并进行必要的配置,让他们可以按照我们想要的方式输出。
-
var evr = options.evr,mod = options.mod;
-
-
if(!modules[mod]) mod ='all';
-
- /* 路径初始化 */
-
-
fileConfig.init(evr);
-
-
gulp.task('clean',function(){
-
-
if(mod ==='all'){
-
-
var clean_path = path.join( evr&& basePath.production || basePath.develop,'/');
-
-
return gulp.src([clean_path],{read:false})
-
-
.pipe(clean());
-
- }
-
- });
-
- /* 获取要build的模块 */
-
-
var parts =[];
-
-
if(mod ==='all'){
-
-
parts = modules;
-
-
}else{
-
-
parts = _.pick(modules,mod);
-
- }
之后我们循环遍历modules,建立相应的task
- /* 分别对模块进行建立 */
-
-
var list =[];
-
-
for(var key in parts){
-
-
(function(key){//闭个包
-
-
var options = fileConfig.getModule(parts[key]);
-
- /* js建立 */
-
-
gulp.task(key+'_js',function(){
-
-
return teemoGulp.buildJs(options.js.src,options.js.dest,evr);
-
- });
-
-
-
- /* css建立 */
-
-
gulp.task(key+'_css',function(){
-
-
return teemoGulp.buildCss(options.css.src,options.css.dest,evr, teemoConfig, options.css.filename);
-
- });
-
-
-
- /* html建立 */
-
-
gulp.task(key+'_html',function(){
-
-
return teemoGulp.buildHtml(options.html.src,options.html.dest,evr, teemoConfig);
-
- });
-
-
-
- /* img建立 */
-
-
gulp.task(key+'_img',function(){
-
-
return teemoGulp.buildImg(options.img.src,options.img.dest,evr);
-
- });
-
-
-
- /* 模块建立 */
-
-
gulp.task(key+'_module',function(cb){
-
-
runSequence(
-
-
[key+'_html',key+'_css',key+'_js',key+'_img'],
-
- cb
-
- );
-
-
});
-
-
})(key);
-
-
list.push(key+'_module');
-
- }
这里用到了runSequence,它制定了task的执行顺序,因为如果不这样做,gulp默认是尽可能的并发执行,就有可能出现 clean没执行完,后续就开始执行的结果,这里注意吧task的回调放在runSequence的最后,保证内部的task执行完,再执行完本身。
当然如果比较简单的,你可以用task的第二个参数来控制task的执行顺序,这里不啰嗦啦。
然后把list返还给你最初的 build
-
var list =Build({
-
-
evr: evr,
-
-
mod: mod
-
- });
-
-
var md5 = evr&&'md5'||[];
-
-
runSequence(
-
-
'clean',list,'md5',cb
-
- );
然后顺序执行即可。
之后到了md5的阶段,md5打包用rev插件即可,但是他默认的md5码是10个,你可以去修改gulp-rev\node_modules\rev-hash路径下的index.js文件,或者干脆做个变量在你的filegulp里配置,单我觉得没必要,就偷懒这里改一下啦。我喜欢用16位
在之后需要把这些加了md5的文件名字换给你引用这些文件的地方,就用到了 rev-replace。
rev在改路径时候会生成一个映射表,你用rev.manifest()即可储存在相应的目录里,然后rev-replace用这个文件替换掉你目标文件的路径即可。
至于cdn,也可以用revReplace里的prefix属性去加前缀,不过他只支持字符串,如果我们是有多个cdn域名的话,返回给他的可能是一个方法,所以这里我们需要改一下rep-replace文件。
找到gulp-rev-replace下的index.js文件。
在第36行加一句
var prefix = typeof options.prefix === 'function' ? options['prefix'](path.basename(file.path)) : options.prefix;
用prefix替换掉一下用到options.prefix的地方。你需要在第60行左右做同样的事情:
-
if(options.manifest){
-
- // Read manifest file for the list of renames.
-
-
options.manifest.on('data',function(file){
-
-
var manifest = JSON.parse(file.contents.toString());
-
-
Object.keys(manifest).forEach(function(srcFile){
-
-
var prefix =typeof options.prefix ==='function'? options['prefix'](path.basename(srcFile)): options.prefix;//这句是加的
-
-
renames.push({
-
-
unreved: canonicalizeUri(srcFile),
-
-
reved: prefix + canonicalizeUri(manifest[srcFile]),
-
-
prefix: prefix //这句也是后加的
-
- });
-
- });
-
- });
-
-
options.manifest.on('end', replaceContents);
-
- }
-
-
else{
-
-
replaceContents();
-
- }
而且你会发现在之后替换的时候也用到了这个,所以你要他当局部变量传进renames里去。想上面写的那样,因为下面一句用到了他:
-
if(rename.prefix){
-
-
contents = contents.split('/'+ rename.prefix).join(rename.prefix +'/');//这句也改了
-
- }
它这替换方式也挺丧良心的···
这样,我们就可以往里面传方法了~
网上找个算cdn域名的方法:
- /*生成hash */
-
-
hashFnv32a :function(str, asString, seed){
-
- /*jshint bitwise:false */
-
-
var i, l,
-
-
hval =(seed ===undefined)?0x811c9dc5: seed;
-
-
-
-
for(i =0, l = str.length; i < l; i++){
-
-
hval ^= str.charCodeAt(i);
-
-
hval +=(hval <<1)+(hval <<4)+(hval <<7)+(hval <<8)+(hval <<24);
-
- }
-
-
if( asString ){
-
- // Convert to 8 digit hex string
-
-
return("0000000"+(hval >>>0).toString(16)).substr(-8);
-
- }
-
-
return hval >>>0;
-
- }
然后我们就可以进行md5加cdn的打包操作了:
- /* md5打包 */
-
-
buildMd5:function(){
-
-
var vp = vinylPaths();
-
-
return gulp.src(path.join(basePath.production,'/**/{images,lib,styles}/**/*.*'))
-
-
.pipe(vp)
-
-
.pipe(rev())
-
-
.pipe(gulp.dest(basePath.production))
-
-
.pipe(rev.manifest())
-
-
.pipe(gulp.dest(basePath.production))
-
-
.on('end',function(){
-
-
var manifest = gulp.src(path.join(basePath.production,"/rev-manifest.json"));
-
-
gulp.src(path.join(basePath.production,'/**/*.{css,html}'))
-
-
.pipe(revReplace({
-
-
manifest: manifest,
-
-
prefix:function(f){
-
- //cdn域名
-
-
var cdns =["s1","s2","s3","s4"];
-
-
-
-
var fileHashCode = teemoGulp.hashFnv32a(f);
-
-
if(fileHashCode <0){
-
-
fileHashCode =0;
-
- }
-
-
var cdn = cdns[fileHashCode % cdns.length];
-
-
return'http://'+cdn+'.tm.sogoucdn.com/w/20141209'
-
- }
-
- }))
-
-
.pipe(gulp.dest(basePath.production))
-
-
.on('end',function(){
-
-
del(vp.paths);
-
-
del(path.join(basePath.production,"/rev-manifest.json"));
-
- })
-
-
-
- })
-
- },
这样,整个的打包就完成了啦,压缩混淆合并加md5加cdn就全都搞定了。
至于加wap的文件夹,就在做一遍之前的操作即可,记得html要在做一遍覆盖操作,也就是三遍。
需要注意的是你改过的插件需要自己存到特定的包管理的地方去,或者存到自己的github上也行,配好ssh就能下。
最后你需要一个 测试的server,这个很好配:
- /* server */
-
-
gulp.task('server',function(){
-
-
var evr = argv.p ||!argv.d;
-
-
gulp.src(evr?basePath.production:basePath.develop)
-
-
.pipe(webserver({
-
-
livereload:true,
-
-
directoryListing:true,
-
-
open:true
-
- }));
-
- });
不过如果你要测试cdn的话,就只能自己配nginx了,gulp-server上倒是能配代理,不过我没用过,应该也好用。
这样,所有的工作就完成了,这样做还是很方便的,比如,主管要求生产环境和开发环境的路径上要在家 一层路径,那么我们直接修改fileConfig里面的配置就可以:
- /* 环境信息 */
-
-
var source ='source',
-
-
develop ='build/develop',
-
-
production ='build/production';
相关推荐
此项目为一个简单的gulp打包项目,可供刚入门同学学习使用。使用到了nodejs、sass、gulp等基础知识,
这是一个基于 Gulp 4 的前端工作流,包含:完善的自动化流程,快捷的调试部署工具,强大的 Web 解决方案等
gulp打包js,min.js,d.ts等
gulp搭建前端框架
gulp教程,详细教你gulp的使用方法 gulp是在webpack之前非常流行的前端自动化打包工具 今天一步一步教你怎么使用gulp来编写前端自动化脚本
基于腾讯 artTemplate 的 gulp 前端模版插件,功能类似于 gulp-file-include 插件。在编写模版时可以使用全部 artTemplate 的语法,引用模版时可以传递 JSON 数据用于渲染模版。同时也支持模版嵌套。 OSC的编辑器我...
基于gulp建造的前端自动化建造适用于中小型项目,快速建造前端项目框架。以及运营活动页,官网类,简单移动端项目,小样本测试等项目启动// 常用命令开发环境: npm run dev生产环境: npm run build// 单任务命令...
一款基于Gulp的前端自动化脚手架,方便本地开发,集html、js压缩、sass、自动添加厂商前缀、精灵图功能于一体
gulp-start一个gulp搭建的自动化构建系统,可以直接上手用的工程介绍gulp-start是一款用于快速搭建前端工程化的项目,可以快速上手,工程化包括对sass、JavaScript、image的资源压缩与打包主要用到的 gulp包列表如下...
Gulp集成前端打包框架 ###框架说明 支持HTML、CSS、JavaScript 压缩混淆 支持CSS、JavaScript 自动引用合并 支持模板include和变量引入 支持CSS、JavaScript内联 更多更能待完善...... ###初始化说明 安装 -- 下载...
基于流的前端自动化构建工具,利用gulp可以提高前端开发效率,特别是在前后端分离的项目中。使用gulp能完成以下任务: 压缩html、css和js 编译less或sass等 压缩图片 启动本地静态服务器 其他 目标 一键安装...
fetool将前端开发人员日常工作整合起来,并提供浏览器多端实时预览功能,能够用于辅助团队规范开发,提高团队的工作效率。
前端开源库-gulp-h5packergulp-h5packer,移动h5页面打包工具,可以根据描述将资源打包进html,替换资源为全局资源包cdn地址,减少请求数量。
gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成;使用她,我们不仅可以很愉快的编写代码,而且大大...
gulp是一个自动化构建工具,主要用来设定程序自动处理静态资源的工作。简单的说,gulp就是用来打包项目的。 官网:https://gulpjs.com/ 中文官网:https://www.gulpjs.com.cn/docs/ Gulp是一款自动构建工具,需要在...
gulp-webpack-project本示例模板这是一份帮助您学习gulp + webpack的项目示例代码。一些副本参考,请根据自己的项目进行进行修改。详情请戳 。学习的正确了解gulp是做什么用的;了解webpack是做什么用的;了解什么是...
Yworkflow是一套基于Gulp,配合阅文前后端分离架构的前端本地模板构建工具
基于gulp的多页应用打包 实现功能主要有 热加载,本地服务器,文件监听,动态刷新 处理图片(优化图片,压缩) 处理scss(压缩合并,兼容前缀,base64,md5,雪碧图,px2rem高清方案) 处理js(模块化开发,压缩合并...
main.js中的引入顺序决定了打包后css的顺序,组件内的样式没有生效可能是被第三方组件样式覆盖了,所以把第三方组件放在前面引入,router放在后面引入,就可以实现组件样式在第三方样式之后渲染。 代码如下: main....
Gulp是一个自动化构建工具,强调的是前端开发的流程,通过配置一系列的task,定义task处理的事物,然后定义执行顺序,来让Gulp执行task,从而构建前端项目的流程,说白了就是用来打包项目。 不管做什么功能,都...