toBeTheLight.github.io 荒原

Gulp搭建多页面工作环境

2017-04-21
toBeTheLight

使用Gulp构建前端开发环境,适用于多静态页的项目。 主要完成Less与ES6的编译,代码压缩,雪碧图生成、js语法检查与实时刷新。 主要运用了现成的gulp插件并对个别插件代码进行修改以满足个人需求。 首先默认已安装了nodenpm,且已熟悉相关用法。

初始化项目

创建package.json

执行 npm init 引导创建一个package.json文件,用来保存项目配置信息与模块依赖。

创建目录结构

dev
|--- css 
|--- img
|--- js
dist
|--- css
|--- img
|--- js
src
|--- less
|--- img
|--- js src中为原始代码 dev为目前为简化逻辑做的中间层 dist中为gulp构建代码

安装gulp与相关插件

安装gulp

我们要将gulp安装两次 首先进行全局安装 npm install -g 再切换至项目目录 npm install gulp --save-dev

所有功能依赖插件的安装

我们选择将http-server安装至全局 npm install http-server

其余本地依赖可根据package.json进行npm install

列举部分插件: 编译Less文件(gulp-less) 添加css前缀(gulp-autoprefixer) 压缩css(gulp-minify-css) js代码校验(gulp-jshint) ES6代码编译(gulp-babel、babel-preset-es2015) 合并js文件(gulp-concat) 压缩js代码(gulp-uglify) 雪碧图生成(gulp-css-spriter) 压缩图片(gulp-imagemin) 自动刷新页面(gulp-livereload) 图片缓存(gulp-cache) 任务提醒(gulp-notify)

建立任务

创建gulpfile.js

在根目录下创建gulpfile.js

加载插件

在gulpfile.js中编写

var gulp = require('gulp'),
    //less的编译
    less = require('gulp-less'),
    //雪碧图合成
    sprite = require('gulp-css-spriter'),
    //自动添加css前缀
    autoprefixer = require('gulp-autoprefixer'),
    //压缩css
    minifycss = require('gulp-minify-css'),
    //js代码校验
    jshint = require('gulp-jshint'),
    //ES6代码编译
    babel = require('gulp-babel'),
    //压缩js代码
    uglify = require('gulp-uglify'),
    //图片压缩
    imagemin = require('gulp-imagemin'),
    rename = require('gulp-rename'),
    //合并js文件
    concat = require('gulp-concat'),
    //更改提醒
    notify = require('gulp-notify'),
    cache = require('gulp-cache'),
    //自动刷新页面
    livereload = require('gulp-livereload');

由于除了gulp插件以外,其他的插件需要分别加载比较麻烦,我们可以使用gulp-load-plugins插件来一次性加载所有package.json中所有gulp插件,用法如下。

var gulpLoadPlugins = require('gulp-load-plugins'),
	plugins = gulpLoadPlugins();
//此时所有的gulp插件都可以以下方式调用
	plugins.jshint();
	plugins.uglify();

img相关任务

分两步完成

//完成图片压缩
gulp.task('img', function() {
  return gulp.src('src/img/**/*')
    .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
    .pipe(gulp.dest('dev/img'))
});
//完成除待生成雪碧图外的图片的转移
gulp.task('images', ['img'], function() {
  return gulp.src('dev/img/**/[^spicon_]*')
    .pipe(gulp.dest('dist/img'))
    .pipe(notify({ message: 'Images move complete' }));
});

js相关任务

//出于目前业务流程的考虑未做js合并
gulp.task('scripts', function() {
    //js代码校验
    return gulp.src('src/js/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
    //js代码编译
    .pipe(babel({  
		presets: ['es2015']  
	}))  
	.pipe(gulp.dest('dev/js'))
    //给文件添加.min后缀
    .pipe(rename({ suffix: '.min' }))
    //压缩脚本文件
    .pipe(uglify())
    //输出压缩文件到指定目录
    .pipe(gulp.dest('dist/js'))
    //提醒任务完成
    .pipe(notify({ message: 'Scripts complete' }));
});

css相关任务

//less编译
gulp.task('toCss', function() {
    return gulp.src('src/less/*')
    .pipe(less())
    //添加前缀
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(gulp.dest('dev/css'))
    .pipe(notify({message:'toCss complete'}))
});
//处理雪碧图并压缩css
gulp.task('stylesWithSprite',function(){
	var timestamp = +new Date();
	return gulp.src('dev/css/*.css')
	.pipe(spriter({
    	 // 生成的spriter的位置
        'spriteSheet': 'dist/img/sprite_'+timestamp+'.png',
        // 生成样式文件图片引用地址的路径
        'pathToSpriteSheetFromCSS': './img/sprite_'+timestamp+'.png'
    }))
//    给文件添加.min后缀
    .pipe(rename({ suffix: '.min' }))
    //压缩样式文件
    .pipe(minifycss())
    //输出压缩文件到指定目录
    .pipe(gulp.dest('dist/css'))
    //提醒任务完成
    .pipe(notify({ message: 'Styles complete' }));
})

由于gulp-css-spriter插件会将所有样式名为background-image的图片都合并为雪碧图,不符合我们的需求,而插件未提供相应配置,所以我们需要对其代码做一定修改。 我们设计所需处理为雪碧图的图片命名格式为spicon_.。 找到gulp-css-spriter/lib/map-over-styles-and-transform-background-image-declarations.js 将对应位置添加正则匹配,修改为如下代码

//判断url是否包含spicon_
if(transformedDeclaration.property === 'background-image'&&/spicon_/i.test(transformedDeclaration.value)){
				return cb(transformedDeclaration,declarationIndex,declarations);
			}
			//判断url是否包含spicon_
			else if(transformedDeclaration.property === 'background'&&/spicon_/i.test(transformedDeclaration.value)){
				var hasImageValue = spriterUtil.backgroundURLRegex.test(transformedDeclaration.value);
				if(hasImageValue){
					return cb(transformedDeclaration,declarationIndex,declarations);
				}
			}

并且我们希望生成的雪碧图中有一定的间距,gulp-css-spriter依赖spritesmith插件,前者未提供此配置,而后者中提供了此项配置,我们同样通过修改源代码完成此需求 找到gulp-css-spriter/index.js 将对应部分改为

'spritesmithOptions': {padding:5},

html相关任务

只做了文件复制移动

gulp.task('html', function() {
    //js代码校验
    return gulp.src('src/*.html')
	.pipe(gulp.dest('dev'))
    .pipe(gulp.dest('dist'))
    //提醒任务完成
    .pipe(notify({ message: 'html complete' }));
});

事件监听部分

gulp.task('watch', function() {
  gulp.watch('src/less/*.less', ['toCss1']);
  gulp.watch('src/less/*.css', ['toCss2']);
  gulp.watch('src/*.html', ['html']);
  gulp.watch('src/js/*.js', ['jsMove']);
  gulp.watch('src/js/my/*', ['scripts']);
  gulp.watch('src/images/**/*', ['img']);
  livereload.listen();
  gulp.watch(['dev/**/*']).on('change', livereload.changed);
});

最终build指令

gulp.task('build', sequence(['images', 'jsMove', 'scripts', 'toCss1','toCss2','html'], 'stylesWithSprite'));

gulp 命令执行

gulp watch

在项目根目录执行指令 gulp watch; 进入dev目录 执行指令 http-server; 激活浏览器liveReload扩展程序; 键入localhost:8080/file.html

gulp build

在项目根目录执行 gulp build

写的好烂啊


上一篇 文章模板

Content