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

编写可维护的 Gruntfile.js的更多相关文章

  1. 如何使用 require.js ,实现js文件的异步加载,避免网页失去响应,管理模块之间的依赖性,便于代码的编写和维护。

    一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...

  2. 前端小白想要编写可维护的js

    我是一名前端小白,之前没写过多少代码,心里没有代码质量这个概念,人人都说代码是团队的产物,应该将代码写规范,但是我对具体什么样的代码是可维护的是茫然的. 我没写过多少代码,本来好多东西就不咋会,每次给 ...

  3. 如何编写可维护的面向对象JavaScript代码

    能够写出可维护的面向对象JavaScript代 码不仅可以节约金钱,还能让你很受欢迎.不信?有可能你自己或者其他什么人有一天会回来重用你的代码.如果能尽量让这个经历不那么痛苦,就可以节省不少时 间.地 ...

  4. js学习笔记-编写高效、规范的js代码-Tom

    编写高效.规范的js代码: 1.变量命名空间问题,尽量使用局部变量,防止命名冲突(污染作用域中的全局变量):全局空间命名的变量可以在对应的文档域任意位置中使用window调用. 2.尽量使用单var定 ...

  5. 《编写可维护的javascript》读书笔记(中)——编程实践

    上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...

  6. 编写可维护的JavaScript代码(部分)

    平时使用的时VS来进行代码的书写,VS会自动的将代码格式化,所有写了这么久的JS代码,也没有注意到这些点.看了<编写可维护的javascript代码>之后,做了些笔记. var resul ...

  7. 拯救一切强迫症 - 读《编写可维护的 JavaScript》(一)

    拯救一切强迫症 - 读<编写可维护的 JavaScript>(一) 本文写于 2020 年 4 月 24 日 我在小学的时候就有接触过编程,所以读大一的时候 C 语言还算是轻车熟路.自然会 ...

  8. grunt使用watch和livereload的Gruntfile.js的配置

    周末在家看angularJS, 用grunt的livereload的自动刷新, 搞了大半天, 现在把配置贴出来, 免得以后忘记了, 只要按照配置一步步弄是没有问题的; 开始的准备的环境安装是: (1) ...

  9. Grunt 自动化部署之css、image、javascript、html压缩Gruntfile.js配置

    grunt.initConfig方法 用于模块配置,它接受一个对象作为参数.该对象的成员与使用的同名模块一一对应. 每个目标的具体设置,需要参考该模板的文档.就cssmin来讲,minify目标的参数 ...

随机推荐

  1. Jenkins项目部署使用教程-----03节点添加

    1)添加节点 系统管理——>管理节点——>新建节点 进入配置界面 点ok进入配置界面配置,——>高级 点击save保存,进入节点,点击Launch agent使得jenkins服务器 ...

  2. RUCM简介

    一.动机 UCM:用例建模,主要用于结构化和文档需求方面. UCSs:用例规格说明书,通常是文本文档,所以描述中不可避免含有歧义. RUCM:限制性用例建模.目标 G1.使UCMs更加可理解并且更精确 ...

  3. js innerText、textContent、innerHTML的区别和各自用法

    //自定义函数 function my$(id) { return document.getElementById(id); } //点击按钮设置div中的文本内容 my$("btn&quo ...

  4. 如何在Qt Creator 创建一个.pri文件

    如何在Qt Creator 创建一个.pri文件 2013年10月09日 ⁄ 综合 ⁄ 共 254字 ⁄ 字号 小 中 大 ⁄ 评论关闭   这个问题很少人写,因为比较简单,但是让却让我花了好大功夫才 ...

  5. mysql5.6 的st_distance 实现按照距离远近排序。

    当前所处在的位置(113.858202 , 22.583819 ),需要查询我附近1000米内的小区,并安装由近到远的顺序排列  SELECT s.id,s.name,s.lng,s.lat, rou ...

  6. C++_异常3-异常机制throw try catch

    下面介绍如何使用异常机制来处理错误. C++异常是对程序运行过程中发生的异常情况的一种响应. 异常提供了将控制权从程序的一部分传递到另一部分的途径. 对异常的处理有3个组成部分: 1)引发异常  -- ...

  7. Codeforces - 38G 可持久化Treap 区间操作

    题意:\(n\)个人排队,每个人有重要度\(p\)和不要脸度\(c\),如果第\(i\)个人的重要度大于第\(i-1\)个人的重要度,那么他们之间可以交换,不要脸度-1,交换后先前的第\(i\)个人也 ...

  8. ZOJ - 2402 DP方案数

    题意:给出m,序列第i位是第i-1位的至少2倍大,的求长度为n且每一位范围均在1-m的序列方案数 对求方案数做不到信手拈来的感觉,需要加强 用简单的预处理和最优子结构能优化到很不错的效率了 #incl ...

  9. Python 实现 ZoomEye API SDK

    版权声明:未经作者授权,禁止转载! ZoomEye想必大家都很熟悉,自从官方开放了API,网上各种版本的SDK乱飞.今天我也来发一个自己写的. 首先我们从https://github.com/SEC0 ...

  10. VUE 日历签到

    <style lang="scss"> @import "../assets/css/px2rem.scss"; .sign-box { width ...