gulp搭建前端自动化开发环境
gulp是基于node编写的一个构建工具,有4个主要的API:
gulp.src() - 输出符合条件的文件
gulp.dest() - 能被pipe进来,并写文件
gulp.task() - 定义任务
gulp.watch() - 监听文件
首先,默认node环境已经安装;
全局安装gulp: npm i -g gulp
新建文件夹,npm初始化:npm init
作为项目开发依赖安装:npm i -D gulp
新建gulpfile.js,
var gulp = require('gulp'); gulp.task('default', function() { console.log('default'); });
执行命令gulp,ok。
一般需要区分开发和生产环境,
gulp.task('default', ['dev']); gulp.task('dev', ['connect', 'watch']); gulp.task('build', ['html-build', 'file-build'], function() { return gulp.src('dist/rev', { read: false }) .pipe(clean()); });
需要的模块:
gulp-connect:开发阶段,因为的前后端分离的项目,所以需要一个web服务器, gulp-connect是一个带有livereload的web服务器
gulp-changed:可以过滤那些改动过的文件
gulp-babel:通过babel来使用新版es
gulp-sass: 编译sass
gulp-clean: 移除文件和文件夹
gulp-rev: 给静态资源文件加上hash
gulp-htmlmin: 压缩html
http-proxy-middleware:一个nodeJS代理的中间件
gulp-plumber:处理pipe破裂导致的错误
gulp-rev-collector : 从manifest中收集数据,然后替换在html模版里的链接
gulp-sourcemaps: 生产sourcemaps
gulp-tag-include-html: 可以使用include标签来将html元素引入到别的文件中
gulp-trim-js-css: 将style标签移动到head标签中,支持sass语法编译 将script标签移动到body的最后,支持es2015语法编译
rimraf: 为node实现的unix命令rm -rf
npm install --save-dev gulp-connect ...
引入,
var sass = require('gulp-sass'), proxy = require('http-proxy-middleware'), sourcemaps = require('gulp-sourcemaps'), babel = require('gulp-babel'), clean = require('gulp-clean'), rev = require('gulp-rev'), revCollector = require('gulp-rev-collector'), htmlmin = require('gulp-htmlmin'), plumber = require('gulp-plumber'), include = require('gulp-tag-include-html'), trimJsCss = require('gulp-trim-js-css'), path = require('path'), connect = require('gulp-connect'), changed = require('gulp-changed'), DEV_PATH = path.resolve(__dirname, './dev'), BASENAME = path.basename(__dirname), DIST_PATH = path.resolve(__dirname, 'dist/www', BASENAME);
开发阶段配置如下,
gulp.task('connect', function() { connect.server({ root: DEV_PATH, port: 8080, livereload: true, middleware: function(connect, opt) { //设置代理 return [ proxy('/index', { target: 'http://youwebsite.com', changeOrigin: true }) ] } }); }); // 数组里的任务会在你当前任务运行之前完成。
gulp.task('watch', ['html', 'js', 'css', 'file'], function() { gulp.watch('src/**/*.html', ['html']); gulp.watch('src/**/*.htm', ['htm']); gulp.watch('src/**/*.js', ['js']); gulp.watch('src/**/*.{css,scss}', ['css']); gulp.watch('src/**/*.!(html|htm|js|css|scss)', ['file']); });
gulp.task('html', function() { return gulp.src('src/**/*.html') .pipe(changed('dev', { hasChanged: changed.compareLastModifiedTime })) .pipe(plumber()) .pipe(include({ begin: '<%', end: '%>' })) .pipe(trimJsCss()) .pipe(gulp.dest('dev')) .pipe(connect.reload()); });
gulp.task('htm', ['html-all'], function(cb) { return gulp.src('src/**/*.html') .pipe(connect.reload()); }); gulp.task('html-all', function() { return gulp.src('src/**/*.html') .pipe(plumber()) .pipe(include({ begin: '<%', end: '%>' })) .pipe(trimJsCss()) .pipe(gulp.dest('dev')); }); gulp.task('js', function() { return gulp.src(['src/**/*.js', '!src/**/lib/**/*.*']) .pipe(changed('dev', { hasChanged: changed.compareLastModifiedTime })) .pipe(plumber()) .pipe(sourcemaps.init()) .pipe(babel({ presets: ['es2015'] })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('dev')) .pipe(connect.reload()); }); gulp.task('css', function() { return gulp.src(['src/**/*.{css,scss}', '!src/**/lib/**/*.*']) .pipe(changed('dev/', { hasChanged: changed.compareLastModifiedTime, //比较修改时间 extension: '.css' //因为是.scss与.css 比较,所以要设置文件后缀 })) .pipe(plumber()) .pipe(sass({ outputStyle: 'expanded' }).on('error', sass.logError)) .pipe(gulp.dest('dev')) .pipe(connect.reload()); }); gulp.task('file', function() { return gulp.src(['src/**/*.!(html|htm|js|css|scss)', 'src/**/lib/**/*.*']) .pipe(changed('dev/', { hasChanged: changed.compareLastModifiedTime })) .pipe(gulp.dest('dev')) .pipe(connect.reload()); });
生产阶段打包时,首先定义clean-build任务,供其他任务使用。
gulp.task('clean-build', function() { return gulp.src(['dist', 'dev'], { read: false }) .pipe(clean()); });
然后分别定义css-build, file-build, js-build, html-build任务,打包得到上线所需代码。
gulp.task('js-build', ['clean-build'], function() { return gulp.src(['src/**/*.js', '!src/**/lib/**/*.*']) .pipe(babel({ presets: ['es2015'], minified: true, comments: false })) .pipe(rev()) .pipe(gulp.dest(DIST_PATH)) .pipe(rev.manifest()) .pipe(gulp.dest('dist/rev/js')); });
gulp.task('css-build', ['clean-build'], function() { return gulp.src(['src/**/*.{css,scss}', '!src/**/lib/**/*.*']) .pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError)) .pipe(rev()) .pipe(gulp.dest(DIST_PATH)) .pipe(rev.manifest()) .pipe(gulp.dest('dist/rev/css')); });
gulp.task('file-build', ['clean-build'], function() { return gulp.src(['src/**/*.!(html|htm|js|css|scss)', 'src/**/lib/**/*.*']) .pipe(gulp.dest(DIST_PATH)); });
gulp.task('html-build', ['js-build', 'css-build'], function() { return gulp.src(['src/**/*.html', '!src/assets/lib', '!src/assets/lib/**', 'dist/rev/**/*.json']) .pipe(include({ begin: '<%', end: '%>' })) .pipe(revCollector()) .pipe(trimJsCss()) .pipe(htmlmin({ removeComments: true, //清除HTML注释 collapseWhitespace: true, //压缩HTML minifyJS: true, //压缩页面JS minifyCSS: true //压缩页面CSS })) .pipe(gulp.dest(DIST_PATH)); });