编写可维护的 Gruntfile.js

news/2024/7/7 6:57:13

load-grunt-tasks 插件

首先介绍下 load-grunt-tasks 这个插件。

我们一般都会把所有用到的插件以及插件的配置写到 Gruntfile.js 里面,对于小项目来说这个文件最终或许不是很大,但是对于大项目、有很多配置或者很多自定义任务的项目来说,最后这个文件都会变得越来越长,维护起来就成了麻烦。比如下面这样:

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        separator: ';'
      },
      dist: {
        src: ['src/**/*.js'],
        dest: 'dist/<%= pkg.name %>.js'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      },
      dist: {
        files: {
          'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
      }
    },
    qunit: {
      files: ['test/**/*.html']
    },
    jshint: {
      files: ['gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
      options: {
        globals: {
          jQuery: true,
          console: true,
          module: true,
          document: true
        }
      }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['jshint', 'qunit']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');

  grunt.registerTask('test', ['jshint', 'qunit']);
  grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
};

这是一个很标准的 Gruntfile.js ,显然也算是很简短的了,但是看起来也有点累觉不爱。于是 load-grunt-tasks 出来帮我们解决了一部分问题。

它会自动读取并加载项目 packge.json 文件中 devDependencies 配置下以grunt-* 开头的依赖库。于是乎我们就可以用一行代码来搞定上面代码中很多行的loadNpmTasks 了。

require('load-grunt-tasks')(grunt);
// 就代替了以下全部
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');

Gruntfile.js 继续廋身

load-grunt-tasks 插件替 Gruntfile.js 省去了那些反复书写的方法调用,接下来就是将整个 Gruntfile.js 变得干净清爽的步骤了。那就是把上面的各种config 分离出去,让它们各自代表自己是属于哪个插件,而不是一口气全写在一起。当然,还有各种用 registerTask 方法定义的自定义任务,也该单独放到相应的文件中。

自定义任务迁移

首先,在项目根目录下建一个名为 tasks 的目录,在这个目录下来编写各种自定义任务。可以一个任务一个 js 文件,也可以多个简单任务在一个 js 文件,看个人喜好吧。然后在 Gruntfile.js 中用一行代码来载入这些自定义任务:

grunt.loadTasks('tasks');  // 即刚刚新建目录的名称

配置项迁移

然后再在这个目录下新建一个名为 options 的子目录(tasks/options),来存放之前说的那些 config 们。为每一类 config 建一个 js 文件,并以配置项节点名作为文件名称,比如下面这样:

tasks
└── options
    └── concat.js
    └── uglify.js
    └── qunit.js
    └── jshint.js

然后在每个文件中导出对应的配置项,拿 concat.js 来说:

module.exports = exports = {
  options: {
    separator: ';'
  },
  dist: {
    src: ['src/**/*.js'],
    dest: 'dist/<%= pkg.name %>.js'
  }
};

最后在 Gruntfile.js 里用 require 将配置逐个引入即可,也可以封装一个函数来做这件事情。

function loadConfig(configPath) {
  var config = {};

  glob.sync('*', { cwd: configPath })
    .forEach(function(configFile) {
      var prop = configFile.replace(/\.js$/, '');
      config[prop] = require(path.join(__dirname, configPath, configFile));
    });

  return config;
}

再改写 Gruntfile.js 中 initConfig 的调用即可。

var _ = require('lodash');
var config = {
  pkg: grunt.file.readJSON('package.json')
};
_.extend(config, loadConfig('./tasks/options/'));
grunt.initConfig(config);

写在最后

于是乎在每个项目中 Gruntfile.js 几乎一致,而且也几乎不会再变更。Gruntfile.js 、自定义任务、任务配置项各司其职,需要变化时只需对相应文件做出调整即可。

就在前些天,又一位 GitHuber 将这个思路封装成了一个库: load-grunt-config ,感兴趣的同学可以看看。

最终的 Gruntfile.js 可以查看这个例子:https://github.com/heroicyang/cnodeclub/blob/master/Gruntfile.js

参考资料

load-grunt-tasks: https://npmjs.org/package/load-grunt-tasks 
More maintainable Gruntfiles:http://www.thomasboyt.com/2013/09/01/maintainable-grunt.html

转载于:https://www.cnblogs.com/frontendBY/p/5305722.html


http://www.niftyadmin.cn/n/3045996.html

相关文章

java restful接口ajax_SSM RESTful ajax——开发Java Web

前段时间在参加学院里的一个比赛的时候和朋友一起弄了一个简单的网络论坛项目&#xff0c;使用的技术有ssm、mysql、ajax、jquery、html等。刚开始的时候打算前后端分离开发&#xff0c;由于以前没有经验&#xff0c;所以就摸索着写。项目中大概是前端编写好html&#xff0c;不…

使用 Named Pipes 创建有效的连接字符串

使用 Named Pipes 创建有效的连接字符串 SQL Server 2008 SQL Server 2005 默认 Microsoft SQL Server 实例侦听“named pipes”协议时&#xff0c;除非用户进行了更改&#xff0c;否则将使用 //./pipe/sql/query 作为管道名称。句点指示该计算机是本地计算机&#xff0c;pip…

数字推盘游戏java_最强大脑数字推盘游戏-最强大脑数字推盘游戏官方版 v1.0预约_手机乐园...

游戏简介最强大脑数字推盘游戏是一款根据同名综艺节目的挑战项目改变制作的益智闯关游戏。游戏中玩家你要走的就是将各个数字合理的进行移动与组合&#xff0c;而且是要在规则的限制下进行移动&#xff0c;这样一来你就能组出对应的数字图片的同时完成关卡的相关挑战要求。当然…

【志银】Dev-Cpp配置OpenGL图形库(成功版本:Dev-Cpp 5.7.1 MinGW 4.8.1)

★配置前须知&#xff1a;Dev-Cpp自带OpenGL的使用和OpenGL简介 (附Dev-Cpp下载地址&#xff1a;http://sourceforge.net/projects/orwelldevcpp/?sourcedirectory) OpenGL简介&#xff1a;OpenGL&#xff08;全写Open Graphics Library&#xff09;是一个功能强大&#xff0c…

Javascript内存泄漏原理

Javascript内存泄漏原理 1.何为内存泄漏&#xff1f; 内存泄漏是指分配给应用的内存不能被重新分配。一块被分配的内存既不能使用&#xff0c;又不能回收&#xff0c;直到浏览器进程结束就会产生内存泄露。在C中&#xff0c;因为是手动管理内存&#xff0c;内存泄露是经常出现的…

彻底解决 SQL Server 无法连接 连接失败

如何解决 SQL Server 2000 中的连接问题 http://support.microsoft.com/kb/827422/zh-cn本文能帮助您解决 Microsoft SQL Server 2000 的连接问题。本文描述了常见连接问题和所能采取的有助于解决连接问题的步骤。 SQL Server 2000 支持 SQL Server 实例和客户端应用程序间的多…

Javascript内存泄漏检测工具

Javascript内存泄漏检测工具 内存泄漏对开发者来说一般很难检测因为它们是由一些大量代码中的意外的错误引起的&#xff0c;但它在系统内存不足前并不影响程序的功能。这就是为什么会有人在很长时间的测试期中收集应用程序性能指标来测试性能。 最简单的检测内存泄漏的方式是用…

关于“实体商城会不会消失”及虚拟现实(Virtual Reality)的一点思考

有句俗话叫“一铺养三代”&#xff0c;在电子商务如此发达的今天还是这种情况吗&#xff1f;现在的淘宝、京东等等电商软件以及微商等虚拟商城越来越流行&#xff0c;仅天猫双十一一天就达到了900多亿的购买量&#xff0c;虚拟商城会取代实体商城吗&#xff1f; 对于这个问题每…