分析 gulp 的运作方式

更新日期: 2020-11-01阅读: 1.8k标签: gulp

要说到 gulp 的运作方式,就不得不提到 vinyl 和 Node.js 的 stream


vinyl

vinyl 是 gulp 所使用的虚拟的文件格式,在它的自述文件是这么说的:“当提到文件时你首先想到的是什么?肯定是路径和内容吧”,它主要记录的信息有:

  • path:文件路径
  • contents:文件内容
  • cwd:程序执行的目录
  • base:用 glob 寻找文件时开始的目录,例如 src/**/*.js,那 base 就会是 src,这可以用来重现目录结构

另外它还有几个函数用来判断这个文件的内容是什么类型的这类操作,到于这个虚拟文件实际上用在什么地方,咱们稍后再说,先创建一个文件试试:

const { readFile } = require('fs/promises')
const Vinyl = require('vinyl')

const file = new Vinyl({
  path: __filename, // 这个文件的路径
  // 在 Node.js 14.8.0 中 支持 top level await,不过还是建议用 async function 封装
  contents: await readFile(__filename),
  cwd: process.cwd(), // 不设定的话默认值为 process.cwd()
  base: process.cwd(), // 不设定的话默认值为 process.cwd()
})

console.log(file) // 这是应该能看到 <File "file.js" <Buffer ...>>

这样就创建好了一个 gulp 用的文件格式,接下来是 Node.js 的 stream。


stream

stream 设计的本意是要处理大文件的,它能一次读取文件的一小部分,然后再传给调用者进行处理:

const { createReadStream } = require('fs')

// 创建一个读取文件的 stream
const stream = createReadStream(__filename)

// 设置文件字符集编码,否则就会以 Buffer (二进制数据) 的格式读取
stream.setEncoding('utf-8')

// 处理数据
stream.on('data', (chunk) => {
  console.log('chunk', JSON.stringify(chunk))
})

// 结束
stream.on('end', () => {
  console.log('end')
})

实际上它是基于 EventEmitter 之上创建的一组 api,比如 on 就是来自于 EventEmitter,只要照着它的模式,也不一定只能传小块的文件,在 Node.js 中的 stream 也有一个对象模式,如果传的数据不是缓冲区或流就应该设置为对象模式,而对象模式跟一般的模式主要的区别就是不需要处理字符集编码。

再回到 gulp,还记得之前说过 src 是回传一个 stream 吗?接下来看看里面到底传的是什么,先写个 gulpfile 来试看看:

exports.stream = function () {
  const stream = src('./src/**.js')
  stream.on('data', (data) => {
    console.log(data)
  })
  return stream
}

输出:

<File "file.js" <Buffer ...>>

没错,这就是 Vinyl 的文件,gulp 用 stream 的对象模式在传输这些文件,plugin 其实上就是回传一个 Transform 的 stream(Node.js 中 stream 的一种,stream 的种类有 Readable、Writeable、Duplex、Transform)来转换这些文件,比下面是一个把文件内容都换成大写的流:

const { Transform } = require('stream')

exports.uppercase = function () {
  return src('./src/**.js')
    .pipe(
      new Transform({
        // 设置为 object mode
        objectMode: true,
        transform(file, _enc, cb) {
          // 把文件内容转换成为字符串
          const content = file.contents.toString()
          // 转为大写后再转回 Buffer 存回去
          file.contents = Buffer.from(content.toUpperCase())
          // 用 callback 回传
          cb(null, file)
        },
      })
    )
    .pipe(dest('upper'))
}

现在我们有了一个把文件全转大写的 plugin了,不过没什么实用上的意义。这样转来转去的效率太低了。

剩下的部分就是 gulp 处理任务的注册与依赖性的逻辑了,依赖性主要是由 undertaker 处理的,不过我觉得这里没什么特别的东西,所以有兴趣就自己去看看吧。


    链接: https://fly63.com/article/detial/10023

    gulpjs的使用,前端构建工具gulpjs的使用介绍及技巧

    gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速度更快。如果你还没有使用过前端构建工具,或者觉得gruntjs太难用的话,那就尝试一下gulp吧。

    使用Gulp进行代码压缩的步骤以及配置

    安装步骤:1.首先确定是否安装了node.js,如果未安装,请先安装node.js;2.确定是否安装了包管理工具npm,如未安装请安装:npm install npm -g;3.安装gulp: npm install gulp --save-dev;

    gulp常用插件_最有用的Gulp插件汇总

    gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器 ,这篇文件整理了一些gulp常用插件

    Gulp4.0入门指南

    gulp4.0分离了cli和核心部分,所以需要分别安装这两个包,另外对环境要求如下:在项目根目录创建gulpfile.js文件(如果使用ts或者babel,也可用gulpfile.ts、gulpfile.babel.js分别代替

    Gulp前端自动化构建工具

    Gulp自动化构建工具可以增强你的工作流程!易于使用、易于学习、构建快速、插件高质!在日常开发中,可以借助Gulp的一些插件完成很多的前端任务。

    使用Gulp压缩混淆JS的相关配置

    在文件根目录初始化npm,出现package.json,在根目录下面新建gulpfile.js文件,并配置,运行命令(顺序不要变,先把ES6转化问ES5,然后开始压缩混淆,uglify不支持ES6压缩混淆,会报错)

    Gulp - 压缩HTML、CSS、JavaScript 程式码

    在网站正式上线前,压缩程式码是必要的过程,因为可以节省空间还能提高网页整体的效能,这里会介绍三压缩程式码的套件,分别是gulp-htmlmin 、gulp-clean-css、gulp-terser。

    内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!