🤖 Grunt / Gulp:任务流时代
一句话定性
它们是前端自动化的”第一代工人”:把压缩、拼接、加 hash、起服务器这些重复手工活交给脚本。但它们只会”按顺序跑任务”,不理解模块之间的依赖关系——这个先天缺陷,注定它们会被打包器取代。
一、它是什么 & 出现的时代
- Grunt(2012) — “JavaScript Task Runner”,配置式任务运行器。你在
Gruntfile.js里用一个巨大的配置对象声明”有哪些任务、每个任务的输入输出是什么”。 - Gulp(2013) — 主打 “code over configuration”(代码优于配置)和 流式(stream) 处理。用 Node.js 的 stream + pipe 把多个处理步骤串成一条数据流水线。
它们诞生在 2013-2018 SPA时代 早期,前端刚开始有”工程”的概念,但模块打包器还没成熟的空窗期。
二、为什么会出现(解决上一代什么痛点)
上一代:全靠手动
- 上线前要手动压缩 JS/CSS、合并文件、给文件名加 hash 做缓存清除。
- 想用 Sass/Less,要手动编译。
- 改一次代码要手动刷新浏览器。
- 这些步骤每次发布都要重复,极易遗漏、极其枯燥。
Grunt/Gulp 的价值:把这些重复劳动写成可复用的任务,一条命令全跑完。 这是前端第一次有了”自动化构建”的意识。
三、核心机制 & 为什么流行
Grunt — 配置式 / 临时文件
每个插件是一个任务,任务之间通过读写磁盘临时文件来传递中间结果。配置 compile → concat → minify,意味着:编译写到磁盘 → 读回来拼接写到磁盘 → 再读回来压缩写到磁盘。多次磁盘 I/O 是它慢的根源。
Gulp — 流式 / 内存管道
Gulp 的关键洞察:别落盘,用内存流。
src('*.js') ──pipe──► babel() ──pipe──► concat() ──pipe──► uglify() ──pipe──► dest('dist')
读文件成流 转译 拼接 压缩 一次性写盘
整条流水线在内存里流动,只在最后写一次磁盘。所以 Gulp 比 Grunt 快,而且 Gulpfile.js 是命令式代码,比 Grunt 庞大的配置对象更直观、更灵活。这就是 “code over config” 的胜利。
| Grunt (2012) | Gulp (2013) | |
|---|---|---|
| 范式 | 配置式(配置对象) | 流式(代码 + pipe) |
| 中间结果 | 写临时文件 | 内存 stream |
| 速度 | 慢(多次 I/O) | 快 |
| 心智模型 | ”声明一堆任务" | "数据流过管道” |
四、带来的新问题 / 副作用
自动化了流程,却没解决模块化
- 不理解依赖图:它们只知道”对一批文件做某种处理”,不知道
a.jsimport 了b.js。它们处理的是”文件”,不是”模块”。- 手动维护文件顺序:concat 的顺序要你自己排,排错了运行时才炸。
- 无法做 code splitting / tree-shaking:因为根本没有依赖图。
- 插件生态各自为政:每个
grunt-contrib-*/gulp-*插件质量参差。
五、为什么会衰落 / 现状
根本原因:它们解决错了问题的层级。
前端真正的痛点不是”如何自动跑脚本”,而是”如何管理模块之间的依赖关系”。Browserify 和 Webpack 直接从”依赖图”这个本质入手——Webpack 不仅能打包,还能顺手把压缩、转译、加 hash 全做了(通过 loader/plugin)。于是 Grunt/Gulp 能做的事,Webpack 全能做,而且 Webpack 还能做它们做不到的 code splitting 和 HMR。
结局:Webpack 普及后,Grunt/Gulp 迅速退场。如今(2026)它们基本只在老项目里残存,新项目不会再选。
六、对后续技术的影响(因果链)
手动跑脚本太枯燥
│
├──► Grunt(配置式任务) ──► 证明"前端需要自动化"
│
├──► Gulp(流式/code over config) ──► 改进了速度和表达力
│
└──► 但都"不理解模块依赖" ──► 解决错了层级
│
▼
[[Browserify]] / [[Webpack]] 从"依赖图"入手 ──► 一举把任务流要做的事全包了
│
▼
任务流时代终结,进入"模块打包"时代
Gulp 的遗产没死透
“流式处理 + 组合小工具”的思想活了下来。今天很多构建工具内部、以及 CI 脚本里,依然能看到 stream/pipe 的影子。
🔗 相关:前端工程化演进史 | Browserify | Webpack | Node.js | 2013-2018 SPA时代