gulp初体验

微信扫一扫,分享到朋友圈

gulp初体验

前段时间我们搞了个研究和测试性质的cesium项目,基本都是前端的东西。也就是说,主要就是一些js。于是想到用gulp待项目进行发布。据说当今最热门的发布工具室webpack,其次是gulp。但webpack适合SPA,单页应用,而gulp适合传统的多页系统。我们项目非SPA,因此选用gulp。

gulp,就是一个项目发布工具,作用我看无非主要就是压缩js\css\html,然后还可以给文件加上版本号。压缩可以起到减少文件尺寸,节约带宽,加快加载,同时有一定保密作用;而加上版本号,则可以使浏览器缓存失效,避免程序已更新,但客户还是看到老效果这种弊端。这个对CDN就非常有用。但是这个功能估计要跟发布时的监控机制(?)结合起来才有意义,如果没有更新的代码,版本号也都跟之前不一样,迫使客户端全部重新加载一遍,反而造成浪费。我还估计,这些发布工具都跟自动部署这些概念有关,但我没有试过,可见多落后。这也是我这次花了一点时间来用一下gulp的原因。

闲话休提,以下是一些笔记:

一、准备环境

0、安装npm

1、安装gulp

npm install --save-dev gulp

也可以缩写成

npm i -D gulp

i就是install,-D 就是 –save-dev。至于–save-dev有什么作用,我搞不大清楚

2、安装各种插件

这些插件在发布时需要用到。

npm i -D gulp-rev gulp-rev-replace gulp-useref gulp-filter gulp-uglify-es gulp-csso gulp-minify-html gulp-clean

3、如果受到蛊惑,使用了淘宝的镜像

,可能会出现类似“ERR!Unexpected end of JSON input while parsing near”这样的错误

则应:

1)删掉package.lock.json

2)清除cache

npm cache clean --force

3)不再使用淘宝镜像

npm set registry https://registry.npmjs.org/

二、编写发布脚本

这个脚本一般叫gulpfile.js。看资料,说可以有多个这样的文件,分别完成不同的任务。我因为不大熟悉,就全部写在一个文件里了。内容其实也是js。用js来发布js。

我这份发布脚本,流程主要是

1)将发布目录清空

2)拷贝一些无须特别处理的文件,如图片,json;还有一些第三方js,它们本身就已经处理过了,直接拷贝就行了。

3)处理css,css文件加上版本号

4)处理js

js我没有加版本号。因为有许多js文件是动态加载的,加了版本号会404。也有一些插件,如gulp-rev-suffix,好像还是一个中国人写的,可以将版本号弄成

<script src="https://www.tuicool.com/articles/qYFNBnZ/script/script-version.js?rev=17a5da6c8a2d875cf48aefb722eefa07"></script>

这种形式。但前提是html里要预留特殊标记:

<script src="https://www.tuicool.com/articles/qYFNBnZ/script/script-version.js?rev=@@version"></script>

我觉得这很扯。

5)处理html

完整示例:

/*
gulpfile.js
*/
const {
 series,parallel,src,dest } = require('gulp');
const rev = require('gulp-rev'),//添加版本号
revReplace = require('gulp-rev-replace'),//更新index.html下的引用
useref = require('gulp-useref'),//合并css或js文件
filter = require('gulp-filter'),//筛选和恢复
uglify = require('gulp-uglify-es').default,//压缩JS文件
csso = require('gulp-csso'),//压缩CSS文件
minifyHtml = require('gulp-minify-html'),//压缩html
clean = require('gulp-clean');//清理文件或文件夹	
//public函数,那么我们发布的时候的命令就是 gulp build	
exports.build = series(
empty,
copy1,copy2,
parallel(css,js),
html
);
const dist = "./dist";
const MANIFEST = dist + "/rev-manifest.json";
function empty(){
//打包前先清掉目标发布文件夹
return src('dist/',{
read: false,allowEmpty:true})
.pipe(clean());
}
function copy1(){
//copy 文件夹libs to dist
return src(['code/libs/**'], {
restore: true})
.pipe(dest(dist + '/libs'));
}
function copy2(){
//直接复制无须处理的文件,如图片,json等等
return src(['code/**/*','!code/**/*.js','!code/**/*.css','!code/**/*.html','!code/libs/**','!code/.svn/**'], {
restore: true})
.pipe(dest(dist));
}
function html(){

let manifest = src("./dist/rev-manifest.json");
//let indexHtmlFilter = filter(['**/*.html', '!**/widget.html'], {restore: true});	
return src(['code/**/*.html','!code/libs/**','!code/.svn/**'], {
 sourcemaps: true })
.pipe(minifyHtml({

empty:true,spare:true,quotes:true
}))
//.pipe(indexHtmlFilter)/*筛选html文件*/
//.pipe(rev())/*生成哈希版本号*/
//.pipe(indexHtmlFilter.restore)/*放回流里*/
.pipe(revReplace({
manifest: manifest}))/*更新index引用*/
.pipe(dest(dist));/*文件流放到dist目录下*/
}
function css(){

return src(['code/**/*.css','!code/libs/**','!code/.svn/**'], {
 sourcemaps: true })
.pipe(useref())/*处理注释压缩*/
.pipe(csso())/*压缩css文件*/
.pipe(rev())/*生成哈希版本号*/
.pipe(dest(dist))
.pipe(rev.manifest(MANIFEST,{
base:dist,merge: true}))
.pipe(dest(dist));/*文件流放到dist目录下*/
}
function js(){

//var jsFilter = filter(['**/*.js','!code/js/lan3d.js'], {restore: true});	
return src(['code/**/*.js','!code/libs/**','!code/.svn/**'], {
 sourcemaps: true })
.pipe(useref())/*处理注释压缩*/
.pipe(uglify())/*压缩js文件*/
//.pipe(jsFilter)/*筛选js文件*/	
//.pipe(rev())/*生成哈希版本号*/
//.pipe(dest('dist'))
//.pipe(rev.manifest(MANIFEST,{merge: true}))
//.pipe(jsFilter.restore)/*放回流里*/
.pipe(dest(dist));/*文件流放到dist目录下*/
}

运行结果

三、要点

1、exports

一般网上的资料说的是gulp.task(),但看gulp官方网站,已经不推荐这种方式了。而是采用 exports.*** 的方式

2、gulp对es6或以上的支持

比如 const,Promise,async await之类的语法,关键是要用这个插件来进行JS压缩:

用这个插件来进行JS压缩gulp-uglify-es,而不是一般资料里说的 gulp-uglify。

千万不要照网上说的什么采用babel或@babel,永远都是报错。害死人!!!

3、一些用法

function html(){

let manifest = src("./dist/rev-manifest.json");
let indexHtmlFilter = filter(['**/*.html', '!**/widget.html'], {
restore: true});
return src(['code/**/*.html','!code/libs/**','!code/.svn/**'], {
 sourcemaps: true })
.pipe(minifyHtml({

empty:true,spare:true,quotes:true
}))
.pipe(indexHtmlFilter)/*筛选html文件*/ //<------------------------
.pipe(rev())/*生成哈希版本号*///
.pipe(indexHtmlFilter.restore)/*放回流里*///<------------------------
.pipe(revReplace({
manifest: manifest}))/*更新index引用*/
.pipe(dest(dist));/*文件流放到dist目录下*/
}

筛选,处理,然后放回流里。本来src这里已经指定了待处理的文件类型(html),然后处理过程中,加入这个筛选,是更精细的范围。处理完之后,放回流里,那么这个筛选结束了。

4、发布之后,一些不那么规范的代码可能会报错。这也算是一种质量控制机制吧。

微信扫一扫,分享到朋友圈

gulp初体验

蓝藻是如何杀死300头大象的

上一篇

云南龙陵发现新物种高黎贡球兰:双层五角状花型 香气馥郁

下一篇

你也可能喜欢

gulp初体验

长按储存图像,分享给朋友