react 学习总结–构建工具Gulp、Browserify(二)
1.html 文件处理
gulp-htmlmin 插件
用于压缩html,可以进行配置,下边是配置信息(选填)
var gulp = require('gulp'),
htmlmin = require('gulp-htmlmin');
gulp.task('htmlmin', function () {
var options = {
removeComments: true,//清除HTML注释
collapseWhitespace: true,//压缩HTML
collapseBooleanAttributes: true,//省略布尔属性的值
removeEmptyAttributes: true,//删除所有空格作属性值
removeScriptTypeAttributes: true,//删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true,//删除<style>和<link>的type="text/css"
minifyJS: true,//压缩页面中的JS
minifyCSS: true//压缩页面中的CSS
};
gulp.src('app/*.html')
.pipe(htmlmin(options))
.pipe(gulp.dest('dist/html'));
});
2.CSS文件处理
gulp-sass 插件
用于sass文件的编译
注意:sass是基于Ruby的,Windows用户需要先安装Ruby,然后通过
gem install sass
安装sass,具体安装请看这里
gulp-sass 安装有的时候会出一些问题,因为依赖于node-sass,所以安装较慢,并且有的时候会中断,而且安装gulp-sass还会出现缺少python环境变量的问题,可以查看这篇文章,寻找解决方案
var sass = require('gulp-sass');
gulp.task('sass', function () {
return gulp.src('./app/scss/**/*.scss')
.pipe(
sass({
outputStyle : 'expanded' //表示输出方式
})
.on('error', sass.logError) //打印错误信心
)
.pipe(gulp.dest('./app/css'));
});
outputStyle
的值一共有:nested, expanded, compact, compressed
,还有一些参数可以看这里试一下
gulp-autoprefixer 插件
使用gulp-autoprefixer根据设置浏览器版本自动处理浏览器前缀。这样我们就不必考虑各浏览器兼容前缀。
var autofx = require('gulp-autoprefixer');
gulp.task('sass', function () {
return gulp.src('./app/scss/**/*.scss')
.pipe(sass({outputStyle : 'expanded'}).on('error', sass.logError))
.pipe(autofx({
browsers : ['last 2 versions','last 2 Explorer versions', 'Android >= 4.0'], //兼容程度
cascade : true, //是否美化属性值,就是设置对其
remove : true //是否去掉不必要的前缀
}))
.pipe(gulp.dest('./app/css'));
});
更多的配置信息,请参考这篇文章
gulp-concat 插件
用于合并文件,可以是有一定顺序的,如下
// 根据 gulp.src 列出的文件顺序,来合并
gulp.task('concat',['sass'], function () {
return gulp.src(["app/css/index.css","app/css/appcom.css","app/css/*.css"])
.pipe(concat('app.css'))
.pipe(gulp.dest('./test/css'));
});
gulp-order 插件
有一个插件可以让文件按照文件名的字母排序来合并,如下(我没有使用)
var order = require('gulp-order');
gulp.task('concat',['sass'], function () {
return gulp.src("app/css/*.css")
.pipe(order(["app/css/index.css","app/css/appcom.css","app/css/*.css"]))
.pipe(concat('app.css'))
.pipe(gulp.dest('./test/css'));
});
// 排序后 appcom.css 的 样式在第一位,index.css 的样式在后边
gulp-clean-css 插件
用于压缩css ,参考
var cssmin = require('gulp-clean-css');
gulp.task('cssmin', ['concat'], function () {
return gulp.src('./test/css/app.css')
.pipe(changed('./dist/css'))
.pipe(cssmin({
advanced: false,//是否开启高级优化(合并选择器等)
compatibility: 'ie7',//保留ie7及以下兼容写法
keepBreaks: true,//是否保留换行
keepSpecialComments: '*'
//保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀
}))
.pipe(gulp.dest('./dist/css'));
});
3.JS 文件处理
gulp-jshint 、jshint-jsx 、jshint-stylish 插件
者三个插件配合使用,用来检测javascript的语法错误的,由于工程是针对 react 的,所以使用
jshint-jsx
插件,使其支持jsx的语法规则,而jshint-stylish
插件只是一个,美化警告格式的插件
要使用插件,首先要安装全局的jshint
npm install jshint -g
,然后在根目录下编写.jshintrc
文件,用于配置语法规则
var jshint = require('gulp-jshint'),
jshintjsx = require('jshint-jsx'),
stylish = require('jshint-stylish');
gulp.task('jshint', function () {
return gulp.src(['./app/js/**/*.js','./app/js/**/jsx'])
.pipe(jshint({ linter: jshintjsx.JSXHINT })) // 配置对jsx的检查
.pipe(jshint.reporter(stylish))
.pipe(gulp.dest('./test/js'));
});
.jshintrc
配置文件
{
"bitwise": true,
"esversion": 6,
"freeze": true,
"latedef": "nofunc",
"newcap": true,
"maxcomplexity": true,
"noempty": true,
"undef": true,
"boss": true,
"unused": true,
"browser": true,
"devel": true,
"expr": true,
"lastsemic": true,
"maxdepth": false,
"maxcomplexity": false,
"node": true,
"globals": {
"BMap": false,
"BMAP_ANCHOR_BOTTOM_RIGHT": false,
"BMAP_ANCHOR_BOTTOM_LEFT": false,
"BMAP_STATUS_SUCCESS": false
}
}
更多详细配置,请看这里
gulp-babel 插件
Babel 是一个 JavaScript 编译器,用于转化你的 JavaScript 代码,由于项目使用了ES6,和 React,所以需要使用babel转码一下,babel,同样提供一些配置的插件,我这里使用了这些:
- babel-preset-es2015: 提供对ES6的编译
- babel-preset-react: 提供对react的编译
- babel-preset-stage-1: 提供阶段1的语法支持(还有其他三个阶段)
- lodash.assign: 支持使用Object.assign()
- babel-plugin-transform-replace-object-assign: 支持对Object.assign()的编译
var babel = require('gulp-babel'); //其他几个插件是babel的不需要在这里引入
gulp.task('babeljs', function () {
return gulp.src(['./app/js/**/*.js','./app/js/**/jsx'])
.pipe(babel({
presets : ['es2015', 'react','stage-1'],
"plugins": [
["transform-replace-object-assign", "lodash.assign"]
]
}))
.pipe(gulp.dest('./test/js'));
});
browserify 插件
browserify
是一个编译工具,通过它可以让服务器端的CommonJS格式的模块运行在浏览器端。我们使用 ES6 的import
和export
等通过babel 翻译后变成require
和exports
等,在浏览器端是无法运行的,因此需要browserify,来转化成浏览器能够识别的代码,同时还可以根据文件的依赖关系,打包成一个文件
reactify 是 browserify的插件,使用reactify把jsx转换成js文件
var browserify = require('browserify'),
reactify = require('reactify'),
source = require('vinyl-source-stream');
gulp.task('browserify',['babeljs'], function () {
var b = browserify({
entries : './test/js/index.js', //入口文件
debug : true
});
return b.transform(reactify)
.bundle()
.pipe(source('bundle.js')) //打包成一个文件
.pipe(gulp.dest('./test/js'));
});
gulp-uglify 插件
gulp-uglify
压缩javascript文件,减小文件大小。
var uglify = require('gulp-uglify');
gulp.task('uglifyjs', ['browserify'], function () {
return gulp.src('./test/js/bundle.js')
.pipe(uglify({
// mangle: true, //是否修改变量名
mangle : {except : ['require', 'exports', 'module', '$']} //排除混淆的关键字
compress: true, //是否完全压缩
preserveComments: 'all' //保留所有注释
}))
.pipe(gulp.dest('./dist/js'));
});
4.图片处理
gulp-imagemin、gulp-cache、imagemin-pngquant 插件
gulp-imagemin
用来压缩图片,imagemin-pngquant
是针对png图片的压缩增强,gulp-cache
能够监控图片,如果被改变了,替换了,才去压缩
var imagemin = require('gulp-imagemin'),
cache = require('gulp-cache'),
pngquant = require('imagemin-pngquant');
gulp.task('minimg', ['removeimg'], function () {
return gulp.src('./test/img/**/*.{png,jpg,gif,ico}')
.pipe(cache(imagemin({
optimizationLevel: 5, // 取值范围:0-7(优化等级)
progressive: true, // 无损压缩jpg图片
interlaced: true, // 隔行扫描gif进行渲染
multipass: true, // 多次优化svg直到完全优化
svgoPlugins: [{removeViewBox: false}],//不要移除svg的viewbox属性
use: [pngquant()] //使用pngquant深度压缩png图片的imagemin插件
})))
.pipe(gulp.dest('./dist/img'))
.pipe(browserSync.stream());
});
详细配置参考文章
5.其他插件
run-sequence 插件
run-sequence
主要用来处理gulp任务的串行还是并行,一般gulp.task 的依赖任务如果超过一个,会同时执行所有的依赖任务,有的时候我们需要他们按照顺序执行,就会用到这个插件
语法规则是
('A','B',['C','D'],'E')
,[]
中的任务是并行的,其他的是按照先后顺序执行的
var runSequence = require('run-sequence');
gulp.task('build', function(cb){ // 这个cb,是个回调
runSequence('clean','copy','md5img',['md5css','md5js'],'md5test',cb);
});
更全面的请查看这里
gulp-md5-assets 插件
给文件添加md5版本号,这个插件添加版本号之后是这样的
<script src="./js/bundle.js?31ecb6f6b0"></script>
但是源文件的名称是不变的 还是
bundle.js
var md5 = require('gulp-md5-assets');
gulp.task('md5css', function () {
return gulp.src('./output/css/*.css')
.pipe(md5(10,'./output/*.html'));
// md5()有两个参数,第一个表示生成后缀的位数,第二个表示在对应的文件中替换文件名
});
gulp-clean 插件
删除相应文件
var clean = require('gulp-clean');
gulp.task('clean', function () {
return gulp.src('./output',{read:false})
.pipe(clean());
});
browser-sync 插件
browser-sync 是一个监听文件变化的工具并能自动刷新浏览器,而且不需要安装浏览器插件,并且它可以在所有连接的浏览器上同步操作例如滚动,点击,刷新或填充表单。移动设备上也同样有效。
var browserSync = require('browser-sync').create(),
reload = browserSync.reload;
gulp.task('master', function () {
browserSync.init({
server : './dist'
});
gulp.watch('./app/scss/**/*.scss', ['cssmin']);
gulp.watch(['./app/js/**/*.js', './app/js/**/*.jsx'], ['uglifyjs']);
gulp.watch('./app/*.html', ['htmltodist']).on('change',reload);
//以上其中一种写法,在HTML文件改变后,触发change事件,然后调用reload方法,刷新页面
});
gulp.task('cssmin', ['concat'], function () {
return gulp.src('./test/css/app.css')
.pipe(changed('./dist/css'))
.pipe(cssmin({
keepSpecialComments : '*'
}))
.pipe(gulp.dest('./dist/css'))
.pipe(browserSync.stream()); //注入刷新页面
});
更详细的配置请看官网
6.可能会遇到的问题
gulp-imagemin、gulp-cache、imagemin-pngquant
这三个插件可能会因为版本问题报错,我之前升了一次版本,结果出了问题,又退回到以前的版本了,下边是可以用的版本号,如果还有问题,那就是跟其他插件的冲突
"gulp-imagemin": "^3.0.3",
"imagemin-pngquant": "^5.0.0",
"gulp-cache": "^0.4.5"
- gulp 的插件有很多,解决同一个问题类似的插件也有很多种,我这里只是列出了我使用的一部分,像是解决版本号MD5的插件就有很多种:
gulp-rev
、gulp-md5-plus
等,如果有需要可以去这个网站查看。