前端构建工具 Gulp 的使用总结


目录

  • why
  • 环境搭建
  • gulp
  • gulpfile.js文件解析
  • 开发部署流程

1.why

  • 自动清除缓存,自动刷新,加速开发调试过程 browserSync or browserSync国内

  • js代码压缩,节省带宽。

  • css文件,加入hash码,方便测试。(已知情况,js修改不用清缓存,css文件需要)

2.环境搭建

windows环境node安装,
可以参考该教程,Linux系统可以参考,
教程一,
教程二

注意事项

如果node下载速度过慢,可以考虑使用国内的node下载站

3.gulp

中文官网

入门指南
  • 全局安装 gulp:
$ npm install --global gulp
  • 作为项目的开发依赖(devDependencies)安装:
$ npm install --save-dev gulp
  • 在项目根目录下创建一个名为 gulpfile.js 的文件:
var gulp = require('gulp');
gulp.task('default', function() {
  // 将你的默认的任务代码放在这
});
  • 运行 gulp:
$ gulp

4.gulpfile.js文件解析

let gulp = require('gulp'),

    // html相关
    htmlmin = require('gulp-htmlmin'), // 去掉html注释

    // css相关
    cleanCss = require('gulp-clean-css'),  // 压缩css

    // js相关
    uglify = require('gulp-uglify'),  // 压缩js
    babel = require('gulp-babel'),    // es6转码
    eslint = require('gulp-eslint'),  // 脚本检查

    // 判断文件是否修改
    changed = require('gulp-changed'),

    // 发生错误后继续进程
    plumber = require('gulp-plumber'),

    // 调试
    debug = require('gulp-debug'), // 打印经过pipe的文件名

    // 日志添加颜色
    chalk = require('chalk'),
    log = console.log,   // 打印

    // 删除文件
    del = require('del'), // 删除旧版本文件

    // 任务执行顺序
    runSequence = require('gulp-sequence'), // 串行任务

    // 服务器
    browserSync = require('browser-sync').create(), // -创建服务器

    //在pipe中使用if判断条件
    gulpif = require('gulp-if'),

    //命令行替换变量
    minimist = require('minimist'),

    // css添加版本号
    rev = require('gulp-rev'),  // 添加MD5后缀
    revCollector = require('gulp-rev-collector');  // 路径替换
    
// Environment setup 环境设置
/*
 * env----代表环境变量
 * 启动gulp命令的几种方式
 * gulp----执行默认操作(gulp --env 0)
 * 开发时直接执行gulp命令就行
 *
 * gulp --env 0-----开发
 *
 * 执行gulp则默认执行  gulp --env 0
 */


let knownOptions = {
    string: 'env',
    default: {env: process.env.NODE_ENV || '0'}
};

let options = minimist(process.argv.slice(2), knownOptions);


//web本地服务器配置
let host = {
    path: 'src/main/app/',   // 文件输出目录即开发目录
    build: 'src/main/webapp/',  // 项目构建目录
};

gulp.task('serve', () => {
    browserSync.init({
        proxy: 'http://192.168.0.103:8080',
        serveStatic: [host.path],
        browser: ['chrome'],
        files: [
            `${host.path}**/*.html`,
            `${host.path}**/*.css`,
            `${host.path}**/*.js`,
            `${host.path}img/!**/!*.*`
        ],
    });
});

// 代码检查
gulp.task('lint', () => {
    return gulp.src([host.path + 'js/**/*.js'])
        .pipe(eslint({
            configFile: '.eslintrc.js',
        }))
        .pipe(eslint.formatEach())
        .pipe(eslint.results(results => {
            log(chalk.gray(`Total Files: ${results.length}`));
            log(chalk.redBright(`Total Errors: ${results.errorCount}`));
            log(chalk.yellow(`Total Warnings: ${results.warningCount}`));
        }))
});

// 代码修复
const isFixed = (file) => {
    return file.eslint !== null && file.eslint.fixed;
};

gulp.task('lint-fix', () => {
    return gulp.src([host.path + 'js/**/*.js'])
        .pipe(eslint({
            fix: true,
        }))
        .pipe(gulpif(isFixed, gulp.dest(host.path + 'js')));
});

// 压缩html
let htmlOptions = {
    removeComments: true,   // 清除注释
    collapseWhitespace: true,  // 压缩html
    removeEmptyAttributes: false, // 删除所有空格作属性值 <input id="" /> ==> <input />
    removeScriptTypeAttributes: false, // 删除<script>的type="text/javascript"
    minifyJS: true, // 压缩页面JS
    minifyCSS: true, // 压缩页面css
};

gulp.task('html', () => {
    return gulp.src(host.path + '**/*.html')
        .pipe(plumber())
        .pipe(changed(host.build))
        .pipe(debug({title: '编译:'}))
        .pipe(htmlmin(htmlOptions))
        .pipe(gulp.dest(host.build))
});

// 压缩css + 添加版本号
gulp.task('mincss', () => {
    return gulp.src(host.path + 'css/*.*')
        .pipe(plumber())
        .pipe(debug({title: '编译:'}))
        .pipe(cleanCss())   //- 压缩处理成一行
        .pipe(rev())    //- 文件名加MD5后缀
        .pipe(gulp.dest(host.build + 'css'))  //- 输出文件本地
        .pipe(rev.manifest())   //- 生成一个rev-manifest.json
        .pipe(gulp.dest(host.build + 'css'));  //- 将 rev-manifest.json 保存到 rev 目录内
});
// 替换css路径
gulp.task('revcss', () => {
    return gulp.src([host.build + 'css/*.json', host.build + '**/*.html']) //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
        .pipe(revCollector())   //- 执行文件内css名的替换
        .pipe(gulp.dest(host.build));  //- 替换后的文件输出的目录
});
gulp.task('css', (cb) => runSequence(['mincss'], ['revcss'])(cb));

// js转码
gulp.task('babel', () => {
    return gulp.src(host.path + '**/*.js')
        .pipe(plumber())
        .pipe(changed(host.build + 'js'))
        .pipe(debug({title: '编译:'}))
        .pipe(babel({
            presets: ['es2015']
        }))
        .pipe(gulp.dest(host.build + 'js'))
});

// js压缩
gulp.task('js', () => {
    return gulp.src(host.path + 'js/**/*.js')
        .pipe(plumber())
        .pipe(changed(host.build + 'js'))
        .pipe(debug({title: '编译:'}))
        .pipe(babel({
            presets: ['es2015']
        }))
        .pipe(uglify())
        .pipe(gulp.dest(host.build + 'js'))
});

// configjs转化压缩
gulp.task('configjs', () => {
    return gulp.src(host.path + 'config.js')
        .pipe(plumber())
        .pipe(changed(host.build))
        .pipe(debug({title: '编译:'}))
        .pipe(babel({
            presets: ['es2015']
        }))
        .pipe(uglify())
        .pipe(gulp.dest(host.build))
});

gulp.task('pageJs', (cb) => runSequence(['js'], ['configjs'])(cb));

// static库文件处理
gulp.task('static', function () {
    return gulp.src(host.path + 'static/**/*')
        .pipe(plumber())
        .pipe(changed(host.build + 'static'))
        .pipe(debug({title: '编译:'}))
        .pipe(gulp.dest(host.build + 'static'))
});

// 图片资源处理
gulp.task('img', () => {
    return gulp.src(host.path + 'img/**/*')
        .pipe(plumber())
        .pipe(changed(host.build))
        .pipe(gulp.dest(host.build + 'img'))
});

// json处理
gulp.task('json', () => {
    return gulp.src(host.path + '**/*.json')
        .pipe(changed(host.build))
        .pipe(debug({title: '编译:'}))
        .pipe(gulp.dest(host.build))
});

// 其他文件
gulp.task('other', () => {
    return gulp.src([host.path + '*.html', host.path + '*.js'])
        .pipe(plumber())
        .pipe(changed(host.build))
        .pipe(debug({title: '编译:'}))
        .pipe(gulp.dest(host.build))
});

// 删除文件
gulp.task('clean', () => {
    del(host.build + '/css');
    del(host.build + '/js');
    del(host.build + '/pages');
    del(host.build + '/static');
    del(host.build + '/img');
    del(host.build + '/index.html');
    del(host.build + '/login.html');
    del(host.build + '/config.js');
    del(host.build + '/*.json');
});

// 构建
gulp.task('build', (cb) => runSequence(
    ['html'], ['css'], ['pageJs'], ['static'], ['img'],['json'],['other']
)(cb));

gulp.task('default', ['serve']);

/* 命令 */
gulp.task('h', () => {
    log(chalk.yellow(''));
    log(chalk.yellow('     开发环境:           gulp  或  gulp --env 0'));
    log(chalk.yellow('     删除文件:           gulp clean'));
    log(chalk.yellow('     检查js代码:         gulp lint'));
    log(chalk.yellow('     修复可修复js代码:   gulp lint-fix'));
    log(chalk.yellow(''));
});

5.开发部署流程

配置好package.json和gulpfile.js文件后。执行

npm install 
注意事项

如果 npm install 时速度过慢,可以用cnpm,(cnpm需要安装,自行Google)。

开发:

所有的修改都是在app文件夹内,build后生成编译后的文件。

gulp // gulp default
部署:
gulp clean

gulp build

此示例为日常使用过程总结,部分代码有待优化。

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

推荐阅读更多精彩内容