再学一次gulp自动化构建项目(含有开发环境和生产环境之分)

前言

用gulp构建官网的项目,起初用别人配置好的gulpfile来构建,后来发现有很多不人性化的操作,比如说在开发调试中,打印出console,按这个去找源文件的出处,发现代码被压缩了,找的可费劲了,说白就是没分配好开发环境和生产环境的。然后是在生产环境中没清除掉console,作为一枚处女座,忍受不了,于是打算大改造gulpfile.js。如有不足之处,请指出来哈,我将会献上我的膝盖~

分配开发环境和生产环境

  • 在本项目的根目录下新建一个文件夹,命名为"config",放入相关gulp的配置文件
  • 在config的文件夹里,新建一个文件,为"index.js",放入相关路径的配置
const SRC_DIR='./src/';   //源路径,不支持相对路径,下面也是
const DEV_DIR='./dev/';   //生成开发环境的文件
const DIST_DIR='./dist/';  //生成生产环境的文件


const config={
    src:SRC_DIR,
    dist:DIST_DIR,
    dev:DEV_DIR,
    html:{
        src:SRC_DIR+'*.html',
        dev:DEV_DIR,
        dist:DIST_DIR
    },
    assets:{
        src:SRC_DIR+'assets/**/*',
        dev:DEV_DIR+'assets',
        dist:DIST_DIR+'assets'
    },
    style:{
        src:SRC_DIR+'style/*.less',  //如果是scss或者css,就改对应的
        dev:DEV_DIR+'css',
        dist:DIST_DIR+'css'
    },
    script:{
        src:SRC_DIR+'script/*.js',
        dev:DEV_DIR+'js',
        dist:DIST_DIR+'js'
    },
    img:{
        src:SRC_DIR+'images/**/*',
        dev:DEV_DIR+'images',
        dist:DIST_DIR+'images'
    }
};

module.exports=config;  //把这个接口暴露给别的文件用
  • 在config中新建两个文件,分别为"gulpfile.dev.js","gulpfile.prod.js"
  • gulpfile.dev.js

const gulp=require('gulp'); //引用gulp插件
const $=require('gulp-load-plugins')();  //自动加载插件,可以省略一个一个引用插件
const config=require('./index.js'); //引用配置的路径文件
const open=require('open'); //开启服务

function dev(){
    gulp.task('html:dev',function(){
        return gulp.src(config.html.src).pipe($.fileInclude()).pipe(gulp.dest(config.html.dev)).pipe($.connect.reload())
    });
    gulp.task('assets:dev',function(){
        return gulp.src(config.assets.src).pipe(gulp.dest(config.assets.dev)).pipe($.connect.reload())
    });
    gulp.task('style:dev',function(){
        return gulp.src(config.style.src).pipe($.less()).pipe($.autoprefixer({
                browseers: ['last 2 versions','Firefox>=20','last 2 Explorer versions','last 3 Safari versions'],
                cascade: true
        })).pipe(gulp.dest(config.style.dev)).pipe($.connect.reload())
    });
    gulp.task('script:dev',function(){
        return gulp.src(config.script.src).pipe($.babel()).pipe($.babel()).pipe(gulp.dest(config.script.dev)).pipe($.connect.reload())
    });
    gulp.task('img:dev',function(){
        return gulp.src(config.img.src).pipe($.imagemin()).pipe(gulp.dest(config.img.dev)).pipe($.connect.reload())
    });
    gulp.task('dev',['html:dev','style:dev','script:dev','img:dev'],function(){
            $.connect.server({
                root:config.dev,
                port:3030,
                livereload:true
            });
            open('http://localhost:3030');
            gulp.watch(config.html.src,['html:dev']);
            gulp.watch(config.html.src,['style:dev']);
            gulp.watch(config.html.src,['script:dev']);
            gulp.watch(config.html.src,['img:dev']);
    })
}
module.exports=dev;
  • gulpfile.prod.js
//配置生产的文件

const gulp=require('gulp'); //引用gulp插件
const $=require('gulp-load-plugins')();  //自动加载插件,可以省略一个一个引用插件
const config=require('./index.js'); //引用配置的路径文件

function prod(){
    gulp.task('html',function(){
        return gulp.src(config.html.src).pipe($.fileInclude()).pipe(gulp.dest(config.html.dist))
    });
    gulp.task('assets',function(){
        return gulp.src(config.assets.src).pipe(gulp.dest(config.assets.dist))
    });
    gulp.task('style',function(){
        return gulp.src(config.style.src).pipe($.less()).pipe($.autoprefixer({
                browseers: ['last 2 versions','Firefox>=20','last 2 Explorer versions','last 3 Safari versions'],
                cascade: true
        })).pipe($.cleanCss({compatibility: 'ie8'}))
        .pipe(gulp.dest(config.style.dist))
    });
    gulp.task('script',function(){
        return gulp.src(config.script.src)
        .pipe($.babel())
        .pipe($.uglify())
        .pipe($.stripDebug({
            debugger:true,console:true,alert:false
        }))
        .pipe(gulp.dest(config.script.dist))
    });
    gulp.task('img',function(){
        return gulp.src(config.img.src).pipe($.imagemin()).pipe(gulp.dest(config.img.dist))
    });
    gulp.task('build',['html','style','script','assets','img'])
}
module.exports=prod;

是不是一目了然呢?

最后新建gulpfile.js

  • 在本项目的根目录下新建一个文件,为gulefile.js,命令行都是通过这个文件启动
const gulp=require('gulp');
const prod=require('./config/gulpfile.prod.js');
const dev=require('./config/gulpfile.dev.js');
const config=require('./config/index.js');
const $=require('gulp-load-plugins')(); 

dev();  //启动开发环境,gulp dev
prod(); //启动生产环境,  gulp prod

gulp.task('clean',function(){
    gulp.src([config.dev,config.dist])
    .pipe($.clean());
});
gulp.task('sprite', function () {  //生成雪碧图,gulp sprite,分别生成dev和dist
  let spriteData = gulp.src(config.src+'/images/sprite_2/*.png')
  .pipe($.spritesmith({
    imgName: 'images/sprite_2.png',
    cssName: 'css/sprite.css',
    padding: 2, // 图片之间的间距
    algorithm: 'left-right', //图片排列格式,默认是top-down,我这里稍微修改下
    algorithmOpts: {sort: false} //是否排序
  }));

  return spriteData.pipe(gulp.dest(config.dist)).pipe(gulp.dest(config.dev));
});

插件介绍

  • gulp-autoprefixer

    • 这个是提供自动添加兼容浏览器的前缀,不需要我们手动添加,不过这并不全的。
  • gulp-clean

    • 每次生成dist和dev,有时为了预防缓存的问题,需要清除的,但每次要手动清除,作为懒癌症的我都嫌弃了,只想用命令运行就清除掉,所以用这个插件的。
  • gulp-clean-css

    • 清除css的注释,减少文件的大小,同时为了减少请求的延迟
  • gulp-connect

    • 这个是创建本地服务器,还能热启动加载
  • gulp-file-include

    • 这个是神器的哈,引用共同的html模板,代码如下
    //meta.html
    <title>@@title</title>
    //index.html
    @@include('./page/meta.html',{
        "title":"首页"
    })
    
  • gulp-imagemin

    • 压缩图片的大小
  • gulp-less

    • 把less转化为css
  • gulp-load-plugins

    • 这个是神器的,当引用多个插件的,一个一个require,多繁杂啊,仅require这个插件的,然后在引用其他的插件时,只要写"$.<插件名>"
    • 插件名的例子如下
    1、gulp-connect
        $.connect
    2、gulp.spritesmith
        $.spritesmith
    3、gulp-file-include
        $.fileInclude
    
  • gulp-strip-debug

    • 去除掉console,alert,debug,对生产环境特别有用。
    • 其实我一开始是拒绝这个插件的,因为这个官方文档没说明不除掉alert的方法,然后没有其他的不错类似这个的插件,只能硬着头皮查更多关于这个的资料,结果找到了,只不过有差别的。下面会给出参考网址
    • 要除掉alert的话,就在生产环境的文件中配置
    $.stripDebug({
        debugger:true,console:true,alert:false
    })
    

    我以为结束了,兴高采烈的运行生产环境,手抖的戳,等了“半天”,没看到alert弹出来,emmm,抱自己痛哭的去看参考网址,卧槽,还要改插件的配置,这个开发者是懒得再多配置了么?好吧~

    • 去node_modules里找gulp-file-include/index.js,然后加options,意思是接受上面的配置
    const through = require('through2');
    const stripDebug = require('strip-debug');
    const PluginError = require('plugin-error');
    module.exports = (options) => {
        return through.obj(function (file, enc, cb) {
            if (file.isNull()) {
                cb(null, file);
                return;
            }
            if (file.isStream()) {
                cb(new PluginError('gulp-strip-debug', 'Streaming not supported'));
                return;
            }
            try {
                file.contents = Buffer.from(stripDebug(file.contents.toString(),options).toString());
                this.push(file);
            } catch (err) {
                this.emit('error', new PluginError('gulp-strip-debug', err, {fileName: file.path}));
            }
            cb();
        });
    };
    
    • 然后再找node_modules里找strip-debug/index.js,修改最后的一段函数
    module.exports = ((source,options) =>{
        options=options || {};
        return rocambole.moonwalk(source, node => {
        options.debugger!==false && stripDebugger(node);
        options.console!==false && stripConsole(node);
        options.alert!==false && stripAlert(node);
        })
    })
    

    ok了,喜极而泣~

  • gulp-ugllify

    • 压缩js的代码
  • gulp.spritesmith

    • 生成雪碧图
  • open

    • 这个适合懒癌症的人,不需要每次启动服务时就手动打开浏览器的

然后至于怎么用,看上面的gulpfile配置喽!

然后献上:https://blog.csdn.net/qq_15096707/article/details/54293203
我是参考这个,思路不错的,可以“去粗取精”

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

推荐阅读更多精彩内容