gulp 单任务多数据源实战:merge-stream 合并独立管线与 globs 数组拼接
gulp 单任务多数据源实战merge-stream 合并独立管线与 globs 数组拼接【免费下载链接】gulpA toolkit to automate enhance your workflow项目地址: https://gitcode.com/gh_mirrors/gu/gulp在同一个 gulp 任务里从多个目录读取文件是构建工作流中的高频需求。本文以 docs/recipes/using-multiple-sources-in-one-task.md 为核心完整讲解两种官方推荐方案用merge-stream将多条独立管线合并为一条以及用gulp.src的 globs 数组特性结合gulp-concat拼接多个来源。读完你将掌握一个任务处理多组文件的两种正确姿势并能理解其底层流式原理与选择依据。场景为什么一个任务需要多个数据源在真实项目中一个任务往往不止处理一组文件。以原文档示例中的静态资源搬运为例bootstrap/js/*.js—— Bootstrap 的 JS 文件需要拷贝到public/bootstrap/jquery.cookie/jquery.cookie.js—— jQuery 插件文件需要拷贝到public/jquery/。虽然可以直接写两个任务分别处理但如果两者属于同一个构建阶段例如都服务于前端资源这一目标把它们放进同一个任务里会让构建逻辑更集中、语义更清晰。这就是单任务多源需求的来源。在 gulp 中每个gulp.src()都会创建一个独立的读取流每个.pipe(gulp.dest())又是独立写入流。同一个任务里出现多个src()时就必须考虑如何把它们组织成一条可被 gulp 正确识别的流。原文档给出了两种官方认可的方案。方案一用 merge-stream 合并多条独立管线这是原文档的第一种做法适用于每组文件的目标目录不同甚至每组文件的处理管线都不同的场景。// npm install --save-dev gulp merge-stream var gulp require(gulp); var merge require(merge-stream); gulp.task(test, function() { var bootstrap gulp.src(bootstrap/js/*.js) .pipe(gulp.dest(public/bootstrap)); var jquery gulp.src(jquery.cookie/jquery.cookie.js) .pipe(gulp.dest(public/jquery)); return merge(bootstrap, jquery); });拆解这段代码可以看到清晰的四步分别创建源流gulp.src(bootstrap/js/*.js)与gulp.src(jquery.cookie/jquery.cookie.js)各自按 glob 模式读取文件产出 Vinyl 对象流分别接上目的地每条流各自.pipe(gulp.dest(...))把文件写到自己的目录。此时bootstrap与jquery都是已经完成读取→写入完整链路的独立流对象合并merge(bootstrap, jquery)把两条流合并成一条合并流两条源流中的文件会按添加顺序依次流出返回合并流return merge(bootstrap, jquery)是最关键的一步。gulp 的任务系统依靠返回的流来判断任务何时完成详见 3-creating-tasks.md 与 4-async-completion.md。如果只返回其中一条流另一条流的写入可能尚未完成任务就会提前结束。把merge的结果作为返回值gulp 会等待两条流全部结束。注意merge-stream是第三方 npm 包npm install --save-dev gulp merge-stream不是 gulp 内置模块但它正是 gulp 生态中处理多源多目标的标准配套工具。方案二globs 数组 gulp-concat 拼接单条管线原文档强调gulp.src会按 globs 数组中声明的顺序发出文件。利用这一点可以把多个来源合并进同一条管线再统一交给下游插件处理。// npm install gulp gulp-concat var gulp require(gulp); var concat require(gulp-concat); gulp.task(default, function() { return gulp.src([foo/*, bar/*]) .pipe(concat(result.txt)) .pipe(gulp.dest(build)); });与方案一相比此方案的关键差异在于gulp.src接受数组查看 src() 的 API 文档globs参数的类型是string | array。传入[foo/*, bar/*]时gulp 会先匹配foo/*的文件再匹配bar/*的文件并按此顺序放入流中共用同一条下游管线文件依次经过concat(result.txt)合并成一个文件再写入build/目录。这正是gulp-concat插件发挥作用的时刻——它读取流中全部文件内容并按到达顺序拼接适用于多源汇聚成单文件/单目录当多个来源的文件最终要合并成一个产物如打包为一个 bundle或写入同一个目标目录时这是最简洁的写法。顺序保证背后的原理glob base方案二能保证拼接顺序与 gulp 的glob baseglob 父路径机制密切相关。在 API Concepts 中有明确说明glob base 是 glob 字符串中任意特殊字符之前的那段路径例如/src/js/**.js的 base 是/src/js/src()生成的所有 Vinyl 对象都会以该 base 作为base属性写入时dest()会移除 base 以保留目录结构。这意味着当你写gulp.src([foo/*, bar/*])时foo/*匹配的文件 base 为foo/bar/*匹配的文件 base 为bar/。虽然它们进入同一条流但各自的相对目录信息依然保留——这也解释了为什么方案二适合统一处理后仍保持各自目录结构或直接按顺序拼接的场景。两种方案如何选择维度方案一merge-stream方案二globs 数组目标目录各源流可写往不同目录通常写往同一目录/同一文件管线处理各源流可挂载不同的插件链所有源文件共享同一条插件链依赖需额外安装merge-stream仅需 gulp 本身拼接需要gulp-concat顺序合并流按传入顺序输出各源流globs 数组内按声明顺序输出文件典型场景多组资源各自拷贝/各自处理多目录源码合并打包成一个 bundle选择要点可以概括为分流用 merge-stream合流用 globs 数组。如果各组文件处理方式不同、目的地不同方案一更合适如果它们要被统一加工并汇聚成单一产物方案二更简洁。源码级原理src/dest 从何而来理解了用法之后看一下当前仓库的实现能更清楚地把握这两种方案在 gulp 整体架构中的位置。在 index.js 中可以看到 gulp 实例的核心方法定义Gulp.prototype.src vfs.src; Gulp.prototype.dest vfs.dest; Gulp.prototype.symlink vfs.symlink;src()与dest()直接来自 vinyl-fs 这个 Vinyl 适配器模块当前仓库的 package.json 中声明了vinyl-fs: ^4.0.2。也就是说无论你用方案一还是方案二底层都是 vinyl-fs 的流在干活——gulp.src负责把文件系统上的真实文件包装成 Vinyl 对象流gulp.dest负责消费这些 Vinyl 对象并写回文件系统。这解释了为什么两种方案能自由组合它们操作的是同一套流协议merge-stream合并的正是这种协议流。同时gulp 官方测试 test/index.test.js 通过hasOwnProperty断言确认了src、dest等 API 均挂在 gulp 实例自身即require(gulp).src是可用的公开接口。关于 src() 的几个相关选项若你的多源任务涉及更复杂的匹配需求可以查阅 docs/api/src.md 中src()的完整选项表其中与多源场景直接相关的包括base显式设置生成 Vinyl 对象的 base控制输出目录结构allowEmpty默认false当某个 glob 只能匹配单个文件如jquery.cookie/jquery.cookie.js且匹配不到时会抛出 File not found with singular glob 错误设为true可抑制ignore从匹配结果中排除指定 globuniqueBy默认path去除流中的重复文件。进阶实践多源管线的错误处理与复用为多源管线统一捕获错误方案一中每条管线都是独立流错误可能发生在任一流上。官方配方 combining-streams-to-handle-errors.md 指出默认情况下流上发出error事件若没有监听器会被直接抛出。更稳妥的做法是用stream-combiner2把一长串流合并成单个流从而只在一处监听errorvar combiner require(stream-combiner2); var uglify require(gulp-uglify); var gulp require(gulp); gulp.task(test, function() { return combiner.obj([ gulp.src(bootstrap/js/*.js), uglify(), gulp.dest(public/bootstrap) ]) .on(error, console.error.bind(console)); });这个思路同样适用于方案一可以把merge(bootstrap, jquery)的结果接入统一错误监听让多源任务失败时错误集中可见。用流工厂复用多源管线如果多个任务都包含多源→统一变换→输出的相同链路官方配方 sharing-streams-with-stream-factories.md 提供了lazypipe方案把共享的插件链封装成工厂函数不同任务中只需pipe(factory())即可复用这也天然兼容多源流各自接同一段工厂管线的组合方式。此外incremental-builds-with-concatenate.md 展示了gulp-cachedgulp-remembergulp-concat配合gulp.watch做增量构建的完整实战其中同样使用了多源聚合 concat的模式可作为方案二在 watch 场景下的延伸参考。小结多源多目标用merge-stream合并各条独立的src→dest管线并务必 return 合并结果保证 gulp 任务在全部写入完成后才结束多源单目标/单文件利用gulp.src支持 globs 数组且按声明顺序发流的特性配合gulp-concat将多目录文件汇聚成一个产物本质src/dest均来自 vinyl-fs两种方案都建立在统一的 Vinyl 流协议之上可自由与错误处理、流工厂、增量构建等其他官方配方组合。更多多源相关实战可继续浏览 docs/recipes/README.md 中的其他配方如 browserify-with-globs.md、minified-and-non-minified.md 等。【免费下载链接】gulpA toolkit to automate enhance your workflow项目地址: https://gitcode.com/gh_mirrors/gu/gulp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

抓住DeepSeek红利:从API直连到Ollama本地部署的实践路径

抓住DeepSeek红利:从API直连到Ollama本地部署的实践路径

简介:《普通人如何抓住DeepSeek红利》是某著名企业发布的第三弹AI应用主题PPT,共65页。内容围绕DeepSeek是什么、能做什么、如何提问三大模块展开,帮助普通用户、职场新人及学生群体理解大模型的能力边界,并掌握用提示词驱动AI完成…

2026/9/19 15:14:48 阅读更多 →
OfficeCLI 折线图全能力指南:用 charts-line 示例玩转 line/stackedLine/percentStackedLine/line3d

OfficeCLI 折线图全能力指南:用 charts-line 示例玩转 line/stackedLine/percentStackedLine/line3d

OfficeCLI 折线图全能力指南:用 charts-line 示例玩转 line/stackedLine/percentStackedLine/line3d 【免费下载链接】OfficeCLI OfficeCLI 是首款也是最佳的专为 AI 代理设计的命令行工具,可用于读取、编辑和自动化处理 Word、Excel 和 PowerPoint 文件…

2026/9/19 15:14:48 阅读更多 →
智慧政务AI大模型平台建设:从选型部署到RAG问答落地

智慧政务AI大模型平台建设:从选型部署到RAG问答落地

简介:这份《智慧政务AI大模型数字化平台建设方案》是一份面向政务信息化规划人员、解决方案架构师及数字政府项目从业者的完整PPT方案,旨在解决政务服务流程繁琐、数据孤岛、响应滞后与智能不足等问题。资源为1个pptx文件,压缩包整体仅3.84MB…

2026/9/19 15:14:48 阅读更多 →

最新新闻

windows95 项目 v86 源码构建与更新指南:fork 分支、五项补丁与探针验证全解析

windows95 项目 v86 源码构建与更新指南:fork 分支、五项补丁与探针验证全解析

windows95 项目 v86 源码构建与更新指南:fork 分支、五项补丁与探针验证全解析 【免费下载链接】windows95 Windows 95 in an app. Runs on macOS, Linux, and Windows. 项目地址: https://gitcode.com/gh_mirrors/wi/windows95 本文档是 windows95 桌面应用…

2026/9/20 21:03:23 阅读更多 →
IsaacLab 电机执行器配置指南:选对模型、配准参数,仿真结果才可信

IsaacLab 电机执行器配置指南:选对模型、配准参数,仿真结果才可信

IsaacLab 电机执行器配置指南:选对模型、配准参数,仿真结果才可信 【免费下载链接】IsaacLab Unified framework for robot learning with multi-physics/renderer support 项目地址: https://gitcode.com/GitHub_Trending/is/IsaacLab IsaacLab …

2026/9/20 21:03:23 阅读更多 →
.NET 运行时 User Secrets 配置提供程序(Microsoft.Extensions.Configuration.UserSecrets)原理与实战

.NET 运行时 User Secrets 配置提供程序(Microsoft.Extensions.Configuration.UserSecrets)原理与实战

.NET 运行时 User Secrets 配置提供程序(Microsoft.Extensions.Configuration.UserSecrets)原理与实战 【免费下载链接】runtime .NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps. 项目地址: https://gitcode.com/GitHub_…

2026/9/20 21:03:23 阅读更多 →
Prettier 相关项目生态指南:从 Linter 集成到工具链扩展的完整地图

Prettier 相关项目生态指南:从 Linter 集成到工具链扩展的完整地图

Prettier 相关项目生态指南:从 Linter 集成到工具链扩展的完整地图 【免费下载链接】prettier Prettier is an opinionated code formatter. 项目地址: https://gitcode.com/gh_mirrors/pr/prettier 本文基于仓库中的 related-projects.md 官方文档整理而成。…

2026/9/20 21:03:23 阅读更多 →
地域名网址查询避坑指南:新手建站防死局实操

地域名网址查询避坑指南:新手建站防死局实操

地域名网址查询避坑指南:新手建站防死局实操 网站做好了没人访问,比没做还让人崩溃。很多新手盯着后台数据发呆,以为是内容不够好,其实八成是基础配置就踩了雷。今天这篇 避坑指南 ,专门针对【地域名网址查询】这个高频但极易出错的环节,拆解从设计到部署的完整链路。…

2026/9/20 21:02:37 阅读更多 →
抖音主页批量下载完整教程:4 步把 douyin-downloader 跑通到无人值守

抖音主页批量下载完整教程:4 步把 douyin-downloader 跑通到无人值守

抖音主页批量下载完整教程:4 步把 douyin-downloader 跑通到无人值守 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser …

2026/9/20 21:02:23 阅读更多 →

日新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →