//引入gulp
const gulp = require('gulp');
//自动加载配置文件中的已安装插件,不需要一个一个require(package.json中声明的依赖)
const gulpLoadPlugins = require('gulp-load-plugins');
//浏览器同步,快速响应文件更改并自动刷新页面
const browserSync = require('browser-sync').create();
//清除文件,支持一个回调函数,类似grunt-contrib-clean
const del = require('del');
//将bower.json中安装的库及依赖(dependence)引进html中,通过识别HTML的注释来识别插入位置
const wiredep = require('wiredep').stream;
//task异步并发执行,解除任务间的依赖,增强task复用,一连串task顺序执行,[]表示可并发执行
const runSequence = require('run-sequence');
const $ = gulpLoadPlugins();
const reload = browserSync.reload;
var dev = true;
//预编译Sass
gulp.task('styles', () => {
return gulp.src('app/styles/*.scss') //指明源文件路径 读取其数据流
.pipe($.plumber()) //错误处理,替换错误的pipe方法,使数据流正常运行
.pipe($.if(dev, $.sourcemaps.init())) //压缩环境出现错误能找到未压缩的错误来源
.pipe($.sass.sync({ //预编译Sass
outputStyle: 'expanded', //outputStyle : 嵌套输出-- nested ,展开输出 ----expanded,紧凑输出 ——--compact,压缩输出 --- compressed
precision: 10, //precision : 精度,小数后10位
includePaths: ['.'] // 指明加载的@import scss的包含路径
}).on('error', $.sass.logError))
//自动匹配浏览器支持的后缀,市场份额,每个浏览器最后2个版本,火狐版本
.pipe($.autoprefixer({browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']}))
.pipe($.if(dev, $.sourcemaps.write())) //map文件命名
.pipe(gulp.dest('.tmp/styles')) //指定输出路径
.pipe(reload({stream: true})); // 任务完成后刷新页面
});
//转化ES6的JS
gulp.task('scripts', () => {
return gulp.src('app/scripts/**/*.js')
.pipe($.plumber())
.pipe($.if(dev, $.sourcemaps.init())) //初始化
.pipe($.babel()) // 编译,ES6转为ES5
.pipe($.if(dev, $.sourcemaps.write('.'))) //生成sourcemap文件,路径为.
.pipe(gulp.dest('.tmp/scripts'))
.pipe(reload({stream: true}));
});
function lint(files) {
return gulp.src(files)
.pipe($.eslint({ fix: true }))
.pipe(reload({stream: true, once: true}))
.pipe($.eslint.format())
.pipe($.if(!browserSync.active, $.eslint.failAfterError()));
}
gulp.task('lint', () => {
return lint('app/scripts/**/*.js')
.pipe(gulp.dest('app/scripts'));
});
gulp.task('lint:test', () => {
return lint('test/spec/**/*.js')
.pipe(gulp.dest('test/spec'));
});
//将CSS合并压缩,JS合并压缩,html压缩,加上时间戳避免缓存
gulp.task('html', ['styles', 'scripts'], () => { ////先执行styles scripts任务
return gulp.src('app/*.html')
//useref:根据注释将HTML需要合并压缩的区块找出来并对文件进行合并,不负责代码压缩
.pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
.pipe($.if(/\.js$/, $.uglify({compress: {drop_console: true}})))
.pipe($.if(/\.css$/, $.cssnano({safe: true, autoprefixer: false})))
.pipe($.if(/\.html$/, $.htmlmin({
collapseWhitespace: true, //压缩HTML
minifyCSS: true, //压缩页面里的CSS
minifyJS: {compress: {drop_console: true}}, //压缩页面里的JS
processConditionalComments: true,
removeComments: true, //清除HTML注释
removeEmptyAttributes: true, //删除所有空格作属性值
removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true //删除<style>和<link>的type="text/css"
})))
.pipe(gulp.dest('dist'));
});
//压缩图片,通过对比图片大小,可以看出压缩了多少
gulp.task('images', () => {
return gulp.src('app/images/**/*')
.pipe($.cache($.imagemin())) //使用gulp-cache只压缩修改的图片,没有修改的图片直接从缓存文件读取
.pipe(gulp.dest('dist/images'));
});
//引用字体文件
gulp.task('fonts', () => {
////main-bower-files会从bower.json文件里寻找定义好的主要文件路径
return gulp.src(require('main-bower-files')('**/*.{eot,svg,ttf,woff,woff2}', function (err) {})
.concat('app/fonts/**/*')) ////将bootstrap-sass的fonts和app下我们自己选用的fonts合并起来
.pipe($.if(dev, gulp.dest('.tmp/fonts'), gulp.dest('dist/fonts')));
});
gulp.task('extras', () => {
return gulp.src([
'app/*',
'!app/*.html'
], {
dot: true
}).pipe(gulp.dest('dist'));
});
//删除任务
gulp.task('clean' , function(){
return gulp.src([
'dist', //删除dist整个文件夹
'dist/test/**/*', //删除dist下的test写任意子文件夹里的文件
'!package.json' //不删除package.json文件
] ).pipe($.clean());
});
// gulp.task('clean', del.bind(null, ['.tmp', 'dist']));
//本地建站和自动刷新
gulp.task('serve', () => {
runSequence(['clean', 'wiredep'], ['styles', 'scripts', 'fonts'], () => {
browserSync.init({
notify: false,
port: 9000,
server: {
baseDir: ['.tmp', 'app'], //确定根目录
routes: {
'/bower_components': 'bower_components'
}
}
});
gulp.watch([ //监测文件变化 实行重新加载
'app/*.html',
'app/images/**/*',
'.tmp/fonts/**/*'
]).on('change', reload);
gulp.watch('app/styles/**/*.scss', ['styles']); //监测变化 执行styles任务
gulp.watch('app/scripts/**/*.js', ['scripts']);
gulp.watch('app/fonts/**/*', ['fonts']);
gulp.watch('bower.json', ['wiredep', 'fonts']);
});
});
gulp.task('serve:dist', ['default'], () => {
browserSync.init({
notify: false,
port: 9000,
server: {
baseDir: ['dist']
}
});
});
gulp.task('serve:test', ['scripts'], () => {
browserSync.init({
notify: false,
port: 9000,
ui: false,
server: {
baseDir: 'test',
routes: {
'/scripts': '.tmp/scripts',
'/bower_components': 'bower_components'
}
}
});
gulp.watch('app/scripts/**/*.js', ['scripts']);
gulp.watch(['test/spec/**/*.js', 'test/index.html']).on('change', reload);
gulp.watch('test/spec/**/*.js', ['lint:test']);
});
// inject bower components
gulp.task('wiredep', () => {
gulp.src('app/styles/*.scss')
.pipe($.filter(file => file.stat && file.stat.size))
.pipe(wiredep({
ignorePath: /^(\.\.\/)+/
}))
.pipe(gulp.dest('app/styles'));
gulp.src('app/*.html')
.pipe(wiredep({
exclude: ['bootstrap-sass'],
ignorePath: /^(\.\.\/)*\.\./
}))
.pipe(gulp.dest('app'));
});
gulp.task('build', ['lint', 'html', 'images', 'fonts', 'extras'], () => {
return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});
gulp.task('default', () => {
return new Promise(resolve => {
dev = false;
runSequence(['clean', 'wiredep'], 'build', resolve);
});
});
参考:https://blog.csdn.net/SeekerTime/article/details/70325162