TAT.mandyluo gulp 进阶-自定义 gulp 插件
In 未分类 on 2016年01月24日 by view: 7,064
10

gulp 已经成为很多项目的标配了,gulp 的插件生态也十分繁荣,截至 2015.1.5,npm 上已经有 10190 款 gulp 插件供我们使用。我们完全可以傻瓜式地搭起一套构建。

然而,我们经常会遇到一种情况,我们好不容易按照文档传入对应的参数调用了插件,却发现结果不如预期,这时候我们就要一点点去排错,这就要求我们对 gulp 插件的工作原理有一定的了解。本文以实现一个 gulp 插件为例,讲解一下 gulp 插件是如何工作的。

需求描述

通常,我们的构建资源为 js/css/html 以及其它的一些资源文件,在开发或发布阶段,js/css 会经过合并, 压缩, 重命名等处理步骤。

有些场景下,我们不能确定经过构建后生成 js/css 的名称或者数量,如此就不能在 HTML 文件中写死资源的引用地址,那么该如何实现一个 Gulp 的插件用以将最终生成的资源文件/地址注入到 HTML 中呢?

假设我们需要实现的插件是这样使用方式:

我们通过一个 HTML 注释用以声明需要依赖的资源,InlineResource 是匹配的关键词,":" 做为分割,/*.css$/,/*.js$/ 是声明要依赖的文件的正则匹配。

在 gulpfile.js 我们需要这边配置:

这里简单介绍下其中的一些方法与步骤:

  • gulp.src('index.html')  会读取文件系统中当前目录下的 index.html,并生成一个可读的 Stream,用于后续的步骤消费

  • InjectResources(stream)  是我们将要实现的插件,它接受一个参数用以获取要注入到 HTML 中的 JS/CSS,此参数应该是一个 Stream  实例,用生成一个 Stream 实例,用于接收并处理上一步流进来的数据

  • hash(options)  是一个第三方插件,用于往当前流中的文件名添加 md5 串,如:gulp-hash

  • gulp.dest('dist')  用于将注入资源后的 HTML 文件生成到当前目录下

我们要关心的是第 2 点:如何接所有的资源文件并完成注入?

我们可以将该逻辑分成 4 个步骤

  1. 获取所有的 js/css 资源
  2. 获取所有的 HTML 文件
  3. 定位 HTML 中的依赖声明
  4. 匹配所依赖的资源
  5. 生成并注入依赖的资源标签

在开编之前,我们需要依赖一个重要的第三方库:map-stream

map-stream  用于获取当前流中的每一个文件数据,并且修改数据内容。

步骤 1 (JS/CSS 资源)

资源流会作为参数的形式传给 InjectResources 方法,在此通过一个异步的实例方法获取所有的文件对象,放到一个资源列表: