百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Gulp vs. Grunt 还在! 但前端已很少提及!

toyiye 2024-05-19 19:35 14 浏览 0 评论

家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

高级前端?进阶

前言

在 JavaScript 领域,技术进步飞快。 大多数现代应用程序都是使用 Vue.js 和 React 等技术构建的,并使用了 Webpack 等模块打包器。

然而,实际上,许多项目并不需要像 Webpack 这样的成熟模块打包器,但仍然需要一种方法来编译其前端资源。 从一定程度上讲,Webpack 并非设计为任务运行器,因此在不打包模块的情况下将其配置为构建资产并不容易。 因此,像 Grunt 和 Gulp 这样的任务运行程序仍然占有一席之地。

1.Gulp/Grunt被Webpack彻底取代了么?

图片来自:https://www.educba.com/gulp-vs-webpack/

Grunt /Gulp与Webpack的区别主要集中在以下几个点:

  • Gulp/Grunt 是一个任务运行器,而 Webpack 是一个打包器,可以为用户打包代码。 因此,Webpack 可以在不借助任何其他应用程序的情况下自行运行大部分功能。
  • Webpack 可以用作中间件,监控系统的任务。 这是在称为 webpack-dev-server 的开发环境中的服务器帮助下完成的,该服务器管理重新加载、热加载。 而 Gulp/Grunt没有这些能力,因为所有工作都被设计为任务。
  • Gulp 中发现错误比在 Webpack 中更难。 在 Webpack 中,很容易找到未运行的代码并在不需要时将其删除,比如死代码消除。 但、Gulp/Grunt 不具备这种能力。
  • Webpack 是一个高级构建系统,会管理文件变更,如果任务在第一次尝试中不起作用,则会重新运行。 Gulp 只能管理单个应用程序,它永远不是 Webpack 的替代品,而 Webpack 可以作为 Gulp 的替代品。

总体来看,Gulp/Grunt 作为一个任务运行器有一定的适用场景,而且以前很多云构建脚本都是基于它们编写。Webpack要完全替换Gulp/Grunt可能还需要一定的时间。本文将重点研究 Grunt 和 Gulp, 以了解它们的限制。

值得注意的是,由于Grunt/Gulp/Webpack都使用 JavaScript,因此用户在从 Gulp 迁移到 Webpack 时不会有任何不适应。

2.Gulp vs Grunt有何不同?

在了解这些构建工具有何不同之前,值得注意的是它们都被设计来做同样的事情:自动化原本必须手动完成的任务。 这些任务包括:

  • 将 Less/Sass 编译为 CSS
  • 连接和压缩 CSS 和 JavaScript
  • linting 代码
  • 优化图像
  • 运行单元测试等等

这两种工具都可以帮助开发自动编译前端资产,并使构建结果保持一致而且更加可靠,而这一切都是通过社区贡献的插件来完成的。 在撰写本文时,Grunt 插件注册表包含 6,250 个插件,而 Gulp 插件注册表包含 4000 多个不同的插件。 尽管 Grunt 在这方面处于领先地位,但两者的数量都相当可观。

3.Grunt 和 Gulp 是如何工作的?

Grunt 通过在名为 Gruntfile.js 的文件中定义任务来工作,该文件的结构与 JSON 非常相似。 可以为每个任务指定配置,Grunt 将按顺序运行这些任务。 该文件易于阅读和理解,这使得 Grunt 可能是这两个构建工具中更直观的一个。

另一方面,Gulp 通过使每个任务定义成为一个在名为 Gulpfile.js 的文件上声明的 JavaScript 函数来关注“代码优于配置”原则。 Gulp 代码通常比 Grunt 代码短得多,因为预先不涉及配置。 然后,开发者可以将函数链接在一起,并行或串行运行,以创建构建脚本。

一大优势是 Gulp 可以利用节点流,这意味着 Gulp 不必将中间文件写入磁盘。 这样做的结果是 Gulp 通常比 Grunt 快得多,但由于使用流和Promise,学习曲线可能稍微陡峭。

构建脚本

比较Grunt与Gulp 的最简单方法是使用每种工具创建相同的构建脚本比较配置文件和性能。

下面创建一个 Gruntfile.js 和一个 Gulpfile.js,它们都执行以下操作:

  • 将 Sass 文件编译成 CSS
  • 连接和缩小 CSS 和 JavaScript
  • 优化图像

首先,确保机器上同时安装了 Grunt 和 Gulp CLI:

npm install -g grunt-cli gulp-cli

接下来安装运行 Grunt 和 Gulp 所需的包。可以通过运行 npm install {package} --save-dev 或将以下行复制到 package.json 并运行 npm install 来手动执行此操作:

{
   "name": "grunt-vs-gulp-demo",
   "version": "1.0.1",
   "devDependencies": {
      // 安装依赖
      "grunt": "^1.1.0",
      "grunt-contrib-concat": "^1.0.1",
      "grunt-contrib-cssmin": "^3.0.0",
      "grunt-contrib-imagemin": "^4.0.0",
      "grunt-contrib-uglify": "^4.0.1",
      "grunt-sass": "^3.1.0",
      "gulp": "^4.0.2",
      "gulp-clean-css": "^4.3.0",
      "gulp-concat": "^2.6.1",
      "gulp-imagemin": "^7.1.0",
      "gulp-sass": "^4.1.0",
      "gulp-stats": "0.0.4",
      "gulp-uglify": "^3.0.2",
      "node-sass": "^4.14.1",
      "time-grunt": "^2.0.0"
   }
}

对于 Grunt,需要在项目的根目录中创建一个 Gruntfile.js。

//Gruntfile.js内容
module.exports = function (grunt) {
   const sass = require('node-sass');
   const mozjpeg = require('imagemin-mozjpeg');
   require('time-grunt')(grunt);

   grunt.initConfig({
      sass: {
         options: {
            implementation: sass
         },
         dist: {
            files: {
               'dist-grunt/css/style.css': 'assets/scss/style.scss'
            }
         }
      },
      concat: {
        // concat操作
         css: {
            files: {
               'dist-grunt/css/styles.css': [
                     'dist-grunt/css/style.css',
                     'assets/css/test.css'
               ],
            },
         },
         js: {
            files: {
               'dist-grunt/js/scripts.js': [
                     'assets/js/test1.js',
                     'assets/js/test2.js'
               ],
            },
         },
      },
      cssmin: {
         dist: {
            files: {
               'dist-grunt/css/styles.min.css': ['dist-grunt/css/styles.css']
            }
         }
      },
      uglify: {
        // 压缩js
         dist: {
            files: {
               'dist-grunt/js/scripts.min.js': ['dist-grunt/js/scripts.js']
            }
         }
      },
      imagemin: {
        // 压缩图片
         dynamic: {
            options: {
               optimizationLevel: 5,
               use: [mozjpeg()]
            },
            files: [{
               expand: true,
               cwd: 'assets/img/',
               src: ['**/*.{png,jpg,gif}'],
               dest: 'dist-grunt/img'
            }]
         }
      }
   });

   grunt.loadNpmTasks('grunt-sass');
   grunt.loadNpmTasks('grunt-contrib-concat');
   grunt.loadNpmTasks('grunt-contrib-cssmin');
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks('grunt-contrib-imagemin');
   grunt.registerTask('default', ['sass', 'concat', 'cssmin', 'uglify', 'imagemin']);
};

Grunt 任务的配置不是很有表现力,但相当容易理解。 此外,因为 Grunt 按顺序运行任务,可以对诸如文件可用之类的事情做出安全的假设(例如,dist-grunt/css/style.css 已在运行 concat 任务之前编译)。

对于 Gulp,需要在项目的根目录中创建一个 Gulpfile.js。

//Gulpfile.js文件内容
const gulp = require('gulp');
const sass = require('gulp-sass');
const concat = require('gulp-concat');
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const imagemin = require('gulp-imagemin');
sass.compiler = require('node-sass');
function scss() {
   return gulp.src('assets/scss/**/*.scss')
      .pipe(sass().on('error', sass.logError))
      .pipe(gulp.dest('dist-gulp/css'));
}

function css() {
   return gulp.src([
         'dist-gulp/css/style.css',
         'assets/css/test.css'
      ])
      .pipe(concat('styles.css'))
      .pipe(gulp.dest('dist-gulp/css'))
      .pipe(concat('styles.min.css'))
      .pipe(cleanCSS())
      .pipe(gulp.dest('dist-gulp/css'));
}

function js() {
   return gulp.src('assets/js/**/*.js')
      .pipe(concat('scripts.min.js'))
      .pipe(uglify())
      .pipe(gulp.dest('dist-gulp/js'));
}

function img() {
   return gulp.src('assets/img/*')
      .pipe(imagemin([
         imagemin.mozjpeg({optimizationLevel: 5})
      ]))
      .pipe(gulp.dest('dist-gulp/img'));
}

exports.default = gulp.parallel(gulp.series(scss, css), js, img);
// 并行运行

Gulp的配置更具表现力,允许开发者以更合乎逻辑的方式进行分组。 同样由于 Gulp 的流实现,每个任务都可以并行运行,这是它比 Grunt 快得多的原因。

但是,需要注意的是要确保不会破坏任何依赖链。 为防止这种情况,可以定义要连续运行的任务,就像 scss 和 css 任务一样,从而可以确保 dist-gulp/css/style.css 在 css 任务需要它时已经编译好了。

4.Gulp和Grunt性能对比

4.1 Grunt

4.2 Gulp

  • Grunt 任务:1.6 秒
  • Gulp 任务:0.84 秒

这些结果并不令人惊讶,但它确实表明 Gulp 比 Grunt 快多少。在小项目中,大约 800 毫秒的差异可能不是什么大问题。 然而,对于大型项目,速度差异会成倍增加,Grunt 最终可能会慢得多。

5.Gulp vs. Grunt vs. Webpack

Gulp和Grunt确实火了很长一段时间,那时候代码构建几乎都是依靠它们完成。但是最近几年仿佛已经销声匿迹,前端已经很少提及它们。而这一切的原因一方面是技术上的,这一点在文章前面已经说过了Gulp和Grunt的诸多局限性,但是另一方面确实是因为很多优秀竞争者的出现,比如文章提及的Webpack。接下来就从各种数据一探究竟!

先看看本文的主角,对Gulp和Grunt做一个简单对比。Github数据表明,Gulp的star有32k,而Grunt只有12k,两者项目开源时间都已经长达10年(Grunt短一年),从这一点上看Gulp明显会优于Grunt。

下面再看看下载量的对比,以过去一年的下载数据来看。不论是Gulp还是Grunt,两者的使用量已经非常稳定,几乎没有增长的趋势,当然也没有下降趋势。而且Gulp的数据表现依然优于Grunt、与Github的数据指标表现一致。

接下来将Webpack加进来,一起对比下三者的数据。由于Webpack的加入,Gulp瞬间被抢去了主角光环,Github的数据显示Webpack的star已经有62k,远远高于Gulp的32k,而且三种项目周期几乎一致。

从过去一年的下载量来看,Gulp/Grunt也瞬间被Webpack秒杀,而且差距不是一点半点(具体查看下图)。根据最近的NPM下载数据,周下载量Webpack(22636k) > Gulp(1180k) > Grunt(673k),而且差距非常大。

从数据上看,属于Gulp和Grunt的时代已经过去了,新的百家争鸣时代又来了。Vite、Webpack、Turbopack等等,谁又是下一个Gulp和Grunt呢?大家拭目以待!

6.本文总结

本文主要和大家介绍下Grunt 、 Gulp与Webpack。文章从Grunt/Gulp与Webpack区别 、Gulp vs Grunt有何不同 、Grunt 和 Gulp 如何工作、Gulp和Grunt性能对比等几个角度展开。相信通过本文的比较,大家对选择Grunt/Gulp还是Webpack都已经比较清楚了。因为篇幅有限,如果有兴趣,文末的参考资料提供了大量优秀文档以供学习。


参考资料

https://deliciousbrains.com/grunt-vs-gulp-battle-build-tools/

https://www.keycdn.com/blog/gulp-vs-grunt

https://www.educba.com/gulp-vs-webpack/

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码