gulp安装那些事

2023-11-04

在Gulp中,使用的是Nodejs中的 stream (流),首先获取到需要的stream,然后可以通过stream的pipe()方法把流导入到你想要的地方,比如Gulp的插件中,经过插件处理后的流又可以继续导入到其他插件中,当然也可以把流写入到文件中。所以Gulp是以stream为媒介的,它不需要频繁的生成临时文件,这也是Gulp的速度比Grunt快的一个原因。
1、安装gulp
1.1 完成后运行全局gulp安装
npm install -g gulp
1.2 切换到项目中,进行局部安装一次,并运行
npm install gulp,如果想在安装时把gulp写进项目的package.json文件的依赖中,需要提前在项目里新建一个package.json文件(文件名称必须叫package.json和gulpfile.js,请叫我严肃脸)。
然后运行命令时,加上--sav-dev 就可以了
npm install --save-dev gulp
1.2.1 在项目中,gulp构建后自动添加版本号

但是由于公司发布系统限制,如果用右面方法实现,每次更新都会积压过多过期无用的文件,我们预期效果是:左边的文件格式,添加版本号;


  1. 分别安装gulp-rev、gulp-rev-collerctor
    npm install --save-dev gulp-rev
    npm install --save-dev gulp-rev-collector

  2. 打开node_modules\gulp-rev\index.js

    第144行 manifest[originalFile] = revisionedFile;
    更新为: manifest[originalFile] = originalFile + '?v=' + file.revHash;

  3. 打开node_modules\rev-path\index.js

    10行 return filename + '-' + hash + ext;
    更新为: return filename + ext;

  4. 打开node_modules\gulp-rev-collector\index.js

    31行 if ( path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' ) !== path.basename(key) ) {
    更新为: if ( path.basename(json[key]).split('?')[0] !== path.basename(key) ) {

1.3 关于gulp安装与环境变量配置,及安装不成功的原因
node与npm都安装正确,但gulp -v时确一直提示不是内部名外部命令....
最后查了N次发现是系统变量配置错误。
首先检查npm prefix
npm config get prefix
这个应该是系统变量中的path的配置;
D:\softwares\Node\node_global; 这个地址是要添加到系统变量中的。如下
高级系统设置
选中path配置,双击或点击编辑
在路径中添加node的根目录与刚才prefix的路径;
记得每个路径结束位置加上分号,再接下条链接
D:\softwares\Node\;D:\softwares\Node\node_global;
NODE_PATH
2、gulp使用方法
2.1 新建gulpfile.js(必须使用这个名字)
在项目中再创建一个gulpfile.js文件,里边可以定义一些方法。
假设gulpfile.js文件中有个default的任务,接下来运行:gulp+task名称
gulp default
会输出default的内容。
并以Finished结束
3、gulp常用插件
3.1 接下来安装及在gulpfile.js文件中配置一些常用的插件
插件的安装方式:
npm install --global xxx 全局安装
npm install xxx --save-dev 本地安装
优缺点如下:
安装方式 缺点 优点
--global 安装会造成很多冗余插件,浪费空间; 只需要安装一次
--save-dev 每个项目都需要重新安装 减少空间,
直接写入package.json
因为在使用 --global 参数的时候 --save 或 --save-dev参数是无效的。
这样就带来一个问题。此时 package.json 中的 dependencies, devDependencies 将无法享受到npm自动更新带来的便利,不使用dependencies, devDependencies 字段对我们的项目管理来说是不可接受的。
项目中调取的插件是从package.json中查看的,如果没有--save-dev,则不会在package.json中依赖注入dependencies。
这篇文章插件写的挺详细的。
自动加载插件
npm install --save-dev gulp-load-plugins
重命名
npm install --save-dev gulp-rename
var rename  =  require("gulp-rename");
// rename via string 
gulp.src("src/hello.txt")
  .pipe(rename("main/goodbye.md"))
  .pipe(gulp.dest("./dist")); // ./dist/main/text/ciao/goodbye.md 
js文件压缩
npm install --save-dev gulp-jsmin
var jsmin  =  require('gulp-jsmin');
var rename  =  require('gulp-rename');
gulp.task('default', function () {
    gulp.src('src/**/*.js')
        .pipe(jsmin())
        .pipe(rename({suffix :  '.min'}))
        .pipe(gulp.dest('dist'));
});
npm install --save-dev gulp-uglify
npm install --save-dev pump
var gulp  =  require('gulp');
var uglify  =  require('gulp-uglify');
var pump  =  require('pump');
gulp.task('compress', function (cb) {
  pump([
        gulp.src('lib/*.js'),
        uglify(),
        gulp.dest('dist')
    ],
    cb
  );
});
css文件压缩
npm install --save-dev gulp-minify-css
npm install --save-dev gulp-cssmin
var gulp  =  require('gulp');
var cssmin  =  require('gulp-cssmin');
var rename  =  require('gulp-rename');
gulp.task('default', function () {
    gulp.src('src/**/*.css')
        .pipe(cssmin())
        .pipe(rename({suffix :  '.min'}))
        .pipe(gulp.dest('dist'));
});
 html文件压缩
npm install --save-dev gulp-html-minify
npm i gulp-htmlmin --save-dev
npm install gulp-processhtml --save-dev
var htmlminify = require("gulp-html-minify");
gulp.task('build-html' , function(){
    return gulp.src("./html-init/**/*.html")
        .pipe(htmlminify())
        .pipe(gulp.dest("./html"))
});
 js代码检查
npm install --save-dev gulp-jshint
npm install --save-dev jshint-stylish
var jshint  =  require('gulp-jshint');
gulp.task('lint', function() {
   return  gulp.src('js/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('YOUR_REPORTER_HERE'));
});
gulp.task('default', () =>
    gulp.src(['file.js'])
        .pipe(jshint('.jshintrc'))
        .pipe(jshint.reporter('jshint-stylish', {beep :  true}))
);
混淆JS代码
npm install --save-dev gulp-obfuscate
var gulp  =  require('gulp');
var obfuscate  =  require('gulp-obfuscate');
 
gulp.task('default', function () {
     return  gulp.src('test.js')
        .pipe(obfuscate());
});
文件合并
npm install --save-dev gulp-concat
var concat  =  require('gulp-concat');
gulp.task('scripts', function() {
   return  gulp.src('./lib/*.js')
    .pipe(concat('all.js'))
    .pipe(gulp.dest('./dist/'));
});
 less和sass的编译
npm install --save-dev gulp-less
npm install --save-dev gulp-sass
//压缩合并css, css中既有自己写的.less, 也有引入第三方库的.css
gulp.task('lessmin', function (done) {
gulp.src(['src/css/main.less', 'src/css/*.css'])
.pipe(less())
//这里可以加css sprite 让每一个css合并为一个雪碧图
//.pipe(spriter({}))
.pipe(concat('style.min.css'))
.pipe(gulp.dest('dist/css/'))
.on('end', done);
});
图片压缩
npm install --save-dev imagemin-pngquant
var imagemin  =  require('imagemin');
var imageminPngquant  =  require('imagemin-pngquant');
imagemin(['images/*.png'], 'build/images', {use :  [imageminPngquant()]}).then(() => {
    console.log('Images optimized');
});
npm install --save-dev gulp-imagemin
var imagemin  =  require('gulp-imagemin');
gulp.task('default', () =>
    gulp.src('src/images/*')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/images'))
);
运行顺序
npm install --save-dev run-sequence
按顺序执行
var runSequence  =  require('run-sequence');
gulp.task('build', function (done) {
runSequence(
['delRevCss'],
['revJs'],
['js'],
['css'],
['html'],
['imagemin'],
done);
});
逻辑代码
npm install --save-dev gulp-if
var gulpif  =  require('gulp-if');
var uglify  =  require('gulp-uglify');
var condition  =  true; // TODO: add business logic 
gulp.task('task', function() {
  gulp.src('./src/*.js')
    .pipe(gulpif(condition, uglify()))
    .pipe(gulp.dest('./dist/'));
});
给资源加时间戳
npm install --save-dev gulp-rev-collector
清除版本号缓存
npm install --save-dev gulp-rev
var rev  =  require('gulp-rev');
gulp.task('default', function () {
     return  gulp.src('src/*.css')
        .pipe(rev())
        .pipe(gulp.dest('dist'));
});
删除当前目录中的build文件夹
npm install --save-dev del
var del  =  require('del');
del(['tmp/*.js', '!tmp/unicorn.js']).then(paths => {
    console.log('Deleted files and folders:\n', paths.join('\n'));
});
4、gulp常用API
gulp.task() gulp.src() gulp.dest() gulp.watch()
具体可查看官方文档
//使用数组的方式来匹配多种文件
4.1 gulp.src();
用来获取流的,方法输入1个glob(比如匹配一个或多个文件的字符串,或者数组)
然后返回一个可以传递给插件的数据流。
gulp.src(globs[, options])gulp.src(['js/*.js','css/*.css','*.html'])
!js/app.js 从匹配结果中排队js/app.js
    *.+(js|css) 匹配根目录下所有后缀为.js或者.css的文件
    * 匹配文件路径中的0个或多个字符,但不会匹配路径分隔符,除非路径分隔符出现在末尾
    ** 匹配路径中的0个或多个目录及其子目录,需要单独出现,即它左右不能有其他东西了。如果出现在末尾,也能匹配文件。
    ? 匹配文件路径中的一个字符(不会匹配路径分隔符)
    [...] 匹配方括号中出现的字符中的任意一个,当方括号中第一个字符为^或!时,则表示不匹配方括号中出现的其他字符中的任意一个,类似js正则表达式中的用法
    ! 匹配任何与括号中给定的任一模式都不匹配的
    ?匹配括号中给定的任一模式0次或1次,类似于js正则中的
    + 匹配括号中给定的任一模式至少1次,类似于js正则中的
    *匹配括号中给定的任一模式0次或多次,类似于js正则中的
    @匹配括号中给定的任一模式1次,类似于js正则中的
排除模式,在数组中的单个匹配模式前加上!即是排除模式
不能在数组中的第一个元素中使用排除模式
gulp.src([*.js,'!b*.js']) //匹配所有js文件,但排除掉以b开头的js文件gulp.src(['!b*.js',*.js]) //不会排除任何文件,因为排除模式不能出现在数组的第一个元素中
4.2 gulp.dest();
gulp.dest(path[,options])
是用来写文件的
var gulp = require("gulp");
gulp.src("script/jquery.js")
.pipe(gulp.dest("dist/foo.js"));
//最终生成文件的路径为 dist/foo.js/jquery.js
解析:gulp.dest(path)生成的文件路径是我们传入的path参数后面再加上
gulp.src()中通配符开始出现的那部分路径
gulp.src('app/src/**/*.css') //此时base的值为app/src,也就是说它的base路径为app/src//设该模式匹配到了文件 app/src/css/normal.css.pipe(gulp.dest('dist')) //用dist替换掉base路径,最终得到 dist/css/normal.css
gulp.src(script/lib/*.js, {base:'script'}) //配置了base参数,此时base路径为script//假设匹配到的文件为script/lib/jquery.js.pipe(gulp.dest('build')) //此时生成的文件路径为 build/lib/jquery.js
4.3 gulp.task();
是用来定义任务的
gulp.task(name[, deps], fn);
deps是当前定义的任务需要依赖的其他任务,为一个数组。
当定义一个简单的任务时,需要传入任务名字和执行函数两个属性;
gulp.task('default',function(){
console.log("hi~");
});
也可以指定一个任务build执行css,js,imgs这三个任务,可以指定数组来完成。
gulp.task('build', ['css', 'js', 'imgs']);
这些任务不是按顺序执行的,可以将函数和数组结合起来指定依赖关系.
ex:定义一个css任务,在执行前检查greet任务是否已经执行完毕。
gulp.task('css', ['greet'],function(){ ...... });
此时,当执行css任务时,gulp会先执行greet任务,然后在它结束后再调用定义的css函数。
也可以定义在gulp开始运行的时候默认执行的任务
gulp.task('default',function(){ ...... });
gulp.task('one',function(){ //one是一个异步执行的任务 setTimeout(function(){ console.log('one is done') },5000);});//two任务虽然依赖于one任务,但并不会等到one任务中的异步操作完成后再执行gulp.task('two',['one'],function(){ console.log('two is done');});
4.4 gulp.watch();
gulp.watch(glob[, opts], tasks)
用来监视文件的变化,当文件发生变化后,利用它来执行相应的任务。
延伸:
基于node的扩展
在sublime中安装SublimeLinter进行js & css代码校验
一、安装SublimeLinter:
1、按下 Ctrl+Shift+p 进入 命令模式(Command Palette)
2、输入pci
3、输入SublimeLinter,进行安装。
4、安装完成以后,出现如下界面:
二、安装SublimeLinter-jshint
1、按下 Ctrl+Shift+p 进入 命令模式(Command Palette)
2、输入pci
3、输入SublimeLinter-jshint,进行安装。
 4、出现如下结果,则说明安装完成,输入  jshint -v可查看安装的jshint版本。
5、现在使用 Sublime Text 编辑 JavaScript 文件,就会有语法检查了!在行号的左侧会有黄色/红色的小圆点提示语法错误,将光标定位到错误的代码里,底部的状态栏会显示错误原因。
三、关于CSS代码检查:
csslint的安装方法与jshint一致,只需要在sublime text 3的package control中再安装SublimeLinter-csslint,然后在命令行中以下代码安装csslint即可。
1 npm install -g csslint
输入 csslint --version可查看安装的csslint版本。
现在使用 Sublime 编辑CSS、JS文件都有自动拼写检查了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gulp安装那些事 的相关文章

  • React18.x + i18next + antd 国际化正确使用姿势及避坑指南

    如果你使用这个教程还不能够解决你的问题的话 直接私信我 免费一对一给你解决 一 使用vite创建一个react项目 具体的创建方法大家参考vite官方文档 大概的操作如下 如果需要更详细的 大家去自行搜索即可 pnpm create vit
  • CSS之背景样式及边框样式

    1 背景样式 常用属性 background color 背景颜色 background image 背景图片 background repeat 背景图片的平铺方式 background position 背景图片的位置 backgrou
  • 打造高大上的Canvas粒子动画

    首先来看下我们准备要做的粒子动画效果是怎么样的 是这样 或者是这样 甚至是这样 很酷炫 那如何去实现类似上面的粒子动画甚至根据自己的喜好去做更多其他轨迹的动画呢 请看下面详细的讲解 技术选择 因为粒子数量很多 而且涉及到图像像素处理 所以这
  • CSS怎么将DIV中的a标签改颜色

    标签默认文字是蓝色 点过后是文字是紫色 想改变标签文字颜色设置方法如下 a color black 设置默认颜色 a link color blue 未访问颜色 a visited color gray 已访问颜色 a hover colo
  • react组件中设置多个className

    错误写法
  • vue 循环遍历 搜寻资料

    写vue 循环遍历的 大全例子解释 转载连接 https www cnblogs com xulei1992 p 6015416 html https www jqhtml com 49765 html https blog csdn ne
  • input标签是什么?input标签属性有哪些

    input标签属于什么标签 input标签属性有哪些 相信刚接触的表单的小白应该很陌生 那么接下来我们就来讲一下input标签属性有哪些 首先小编在这里谢谢大家一直的支持 每天都会更新十个web前端基础内容 需要的可以关注我 另外也可以进我
  • ES6语法知识点

    目录 let const 常用 暂时性死区 const 建议 箭头函数 常用 建议 iterator迭代器 解构赋值 常用 建议 剩余 扩展运算符 常用 扩展运算符 剩余运算符 在对象中使用扩展运算符 建议 对象属性 方法简写 常用 对象属
  • 发布npm包-简要记录

    1注册账号 注册npm账号 需要邮箱 激活npm账号 npm账号注册成功以后会收到邮件 邮件中有个链接 点进去进行激活 2创建项目 npm init 创建项目 name 命名规则 不能包含大写字母 空格及下滑线 version 创建时候默认
  • uniapp的那些坑

    1 selectedColor不起作用 1 查看位置是否写对 与lis同级 2 是否为16进制 selectedColor写的rgb不支持 3 是否被其他样式覆盖 其他地方也设置过selectedColor 可以全局搜索一下 2 pages
  • Web启动项目走Https协议(Webpack版,Umi版和Host代理版)

    需求 Web项目的启动 一般是默认的http协议 在某些业务需求时 需要走https来调试 Webpack版本 只需在webpack的devServer中配置就可以了 devServer host 0 0 0 0 port 8080 htt
  • CSS 学习笔记(基础)

    用来控制网页表现的语言 CSS Cascading Style Sheet 层叠样式表 然后我们继续看看 W3C 标准 结构 HTML 表现 CSS 行为 JavaScript CSS导入方式 选择器 属性 由于网页的框架结构是由HTML实
  • flex布局宽高度设置不成功

    flex布局中 会出现是在宽高 但是不起作用 那是因为flex布局当不够的时候自动压缩了 可以选择 让其不压缩 flex shrink 0 然后在设置宽高 或者利用复合属性 flex 0 0 83rpx 这篇博客是对flex布局的讲解 以及
  • (一)软件架构概述

    1 系统结构 B S架构 Browser Server 浏览器 服务器的交互形式 Browser支持哪些语言 HTML CSS JavaScript 写HTML CSS JavaScript代码的这波人职位叫做 WEB 前端开发工程师 Ja
  • 解决css中上下外边距(margin)在父元素中溢出的问题

    两个办法 给父元素添加overflow hidden 即可 给父元素添加透明边框border 1px solid transparent 给父元素添加伪元素 before after content display table 改变光标的颜
  • 谷歌(Chrome)浏览器自定义插件

    准备 1 js文件 需要的功能逻辑 2 插件主入口及配置 manifest json 3 插件图标 目录结构 添加插件流程 选择插件文件夹 代码 manifest json name 百度 manifest version 2 versio
  • 点击按钮复制链接

    做点击按钮复制链接 网上找的方法是用原生js document execCommand Copy window clipboardData setData Text url value 发现微信上存在不兼容 在安卓和PC段都可以 但是在苹果
  • js实现鼠标悬停显示title效果

  • React 笔记 jsx

    严格约定 React 组件必须以 大写字母开头 而 HTML 标签则必须是小写字母 React JSX JSX 是由 React 推广的 JavaScript 语法扩展 用于表达组件的 特殊语法的 js 函数 要求标签必须闭合 返回的组件必
  • 第8章 多媒体嵌入

    学习目标 了解视频 音频嵌入技术 能够总结HTML5视频 音频嵌入技术的优点 了解常用的视频文件格式和音频文件格式 能够归纳HTML5支持的视频和音频格式 掌握HTML5中视频的嵌入方法 能够在HTML5页面中添加视频文件 掌握HTML5中

随机推荐

  • CentOS7上安装 Apache

    在 CentOS 7 上安装 Apache 的方法如下 1 首先打开终端 并使用 sudo 命令以 root 权限运行 sudo su 2 更新软件包列表 yum update 3 安装 Apache 服务器和常用工具 yum instal
  • C++【对象模型】

    文章目录 索引 一 默认构造函数 1 何时默认构造函数会自动生成 2 编译器合成有用的构造函数四种情况 2 1 类中内含带有默认构造的类成员 2 2 带有默认构造的基类 2 3 带有虚函数的类 2 4 带有一个虚基类的类 索引 C 对象模型
  • Jetbrain项目管理全家桶

    sudo mkdir p m 750 opt hub data opt hub conf opt hub logs opt hub backups sudo chown R 13001 13001 opt hub data opt hub
  • ppt地图分布图一块一块的怎么做_学会“地图话”,走遍天下都不怕!

    PPT是维他命 hi 这里是PPT是维他命 谢谢你的关注 我们一起进步 hello大家 又 好久不见了 心虚 距离上次更新已经快两个月了 说好的半月更 说好的尽快发地球公转 都是我的锅 从十一开始因为加课时一直在调整节奏 忙到原地陀螺转 这
  • Vue中使用七牛云上传报错o.upload.addEventListener is not a function以及其他报错问题

    1 运行提示o upload addEventListener is not a function 解决方案 此方法不是根本解决办法 问题3的解决办法是最终解决方案 找到node modules mockjs dist mock js 第8
  • 北京大学肖臻老师《区块链技术与应用》公开课 06-BTC-网络

    总述 用户将交易发布到比特币网络上 节点收到这些交易之后 将其打包到区块里 节点将区块发布到比特币网络中 新发布的区块在比特币网络中如何传播 The Bitcoin Network 比特币工作在应用层 application layer B
  • 羞羞的报告:2020年轻人性爱数据报告。

    VI 腾讯新闻谷雨数据出品 ID guyudata 转自 小蚊子数据分析 今天开工第一天 就来分享点数据相关的轻松的内容 2020年 多少人实现了性爱需求的满足 多少人处于性需求的 贫困线 以下 在性幻想 性需求的表达等方面 男女之间的抉择
  • 云杰恒指:7.29恒指期货实盘指导交易复盘

    对于一个成熟交易者来说 盈利是市场给的 没有属于我们的行情 我们坚持不会开仓 看不懂的行情不开仓 直到交易信号出现 然后精准出击 获得属于我们自己的利润 曾有人对技术分析过度依赖 在一次爆仓后找到我 我给出的答案是技术分析本来就是一会准一会
  • 一致性 Hash 算法(分布式或均衡算法)

    简介 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希 DHT 实现算法 设计目标是为了解决因特网中的热点 Hot spot 问题 初衷和CARP十分类似 一致性哈希修正了CARP使用的简单哈希算法带来的问题 使得分布式哈希 D
  • Python爬取研招网数据

    一 爬虫定制部分 导入相关的包 import requests import lxml html import chardet import pandas as pd import numpy as np 请求头获取页面 def get p
  • Spring Boot 代码混淆(proguard-maven-plugin的使用说明)

    什么是代码混淆 就是将代码的通过工具使其可读性变差 越差越好 Proguard是什么 官网地址 www guardsquare com proguard 该工具主要是为了实现Java以及Android App的代码混淆工作 从官网的说明可以
  • 批量爬取百度图片

    输入关键字和要爬取的数量 直接爬取图片并保存到本地 这个比较简单 直接使用即可 import requests import json word input 输入您需要爬取的关键字 page num int input 需要爬取多少页 一页
  • Linux 进程手撕笔记——万字深剖详解

    目录 传统艺能 冯 诺依曼体系 内存 控制器 如何搞管理 进程 操作系统立大功 进程查看 进程的 PID 获取进程 PID fork 进程状态 Linux 进程状态 进程优先级 为什么会有优先级 Linux 优先级相关操作 传统艺能 小编是
  • Java线程池的正确关闭方法,awaitTermination还不够

    问题说明 今天发现了一个问题 颠覆了我之前对关闭线程池的认识 一直以来 我坚信用shutdown awaitTermination关闭线程池是最标准的方式 不过 这次遇到的问题是 子线程用到BufferedReader 而BufferedR
  • 利用STM32CubeMX软件生成USB_DEVICE_SD卡虚拟U盘

    一 测试平台 MCU STM32F429NIH6 工具 STM32CubeMX软件 编译软件 MDK 二 配置步骤 1 打开STM32CubeMX软件 创建新的工程文件 先生成一个的串口的收发例程 需要实现将串口收到的数据发送的出来 生成串
  • 【华为OD机试 】新工号中数字的最短长度(C++ Java JavaScript Python)

    华为od机试共有3道题 分值为100 100 200 总分为400分 考试时间 2 5h 每道题目都需要通过测试用例来得分 全通过则为满分 华为od机试是在牛客网上进行的 采用ACM模式 华为od机试目标院校分数为160分 华为od机试非目
  • ideavim 解决烦人的中英文切换问题

    先下载插件IdeaVimExtension 然后终端输入 set keep english in normal and restore in insert 注意前面有个冒号
  • 利用遗传算法求解函数极值

    1 利用遗传算法求解函数极值 例1 利用遗传算法求函数 f x 11sin 6x 7cos 5x x 的最大值点 解 在MATLAB中编制绘制函数曲线的代码 运行得到题中函数的曲线图如下图所示 从下图中可以看出 该函数有多个极值点 如果使用
  • 使用ES6编写一个超简单的搜索算法

    自从chrome和ES6的普及 JS的性能和科学算法也日新月异 这次我就分享一个超简单的搜索算法 let result appData map item gt Object assign item count arr map i gt it
  • gulp安装那些事

    在Gulp中 使用的是Nodejs中的 stream 流 首先获取到需要的stream 然后可以通过stream的pipe 方法把流导入到你想要的地方 比如Gulp的插件中 经过插件处理后的流又可以继续导入到其他插件中 当然也可以把流写入到