目的:自动化构建项目;完成压缩,编译,单元测试,代码检查以及打包发布的任务。
生成线上调试source map,代码行统计。
常用Grunt任务:
Cache :cache-breaker、usemin + rev
CSS :grunt-recess、less、cssmin、uncss、csslint(CSS检测)
JS :uglify(压缩JS,Beautify JS,生成线上调试source map)、 jshint(JS代码检测及检测规则配置)、sloc(代码行统计)、ng-min(Angular代码压缩)、plato(代码复杂度、可维护性)
HTML :html-validation、
测试 :jasmine、qunit
基本任务 :clean、concat、copy、watch
Cache清除缓存任务
. usemin + rev
目的是清除浏览器缓存。
给静态文件重名后,再将html、css中的静态文件引用的名称替换成新文件名。
rev给静态文件重命名。usemin替换html、css中引用的静态文件名。
虽然usemin任务执行之前会自动执行 concat、uglify、cssmin任务。一般还是要自己定义任务:要先执行clean清除重命名的静态文件;concat合并文件;recess重新编译和压缩css文件;uglify重新压缩js文件。最后再执行useminPrepare,rev,usemin。
useminPrepare: { src: "<%= site.destination %>/{,*/ /* }*.html", options: { dest: "<%= site.destination %>", root: "<%= site.destination %>" } }, rev: { options: { algorithm: 'md5', length: 8 }, assets: { files: { src: [ '<%= kui_css %>', '<%= kui_js %>', '<%= kuidoc_css %>', '<%= kuidoc_js %>', './images/{,*/ /* }*.{png,jpg,jpeg,gif,webp}', ] } } }, usemin: { html: ["<%= site.destination %>/{,*/ /* }*.html" ], css: ["./css/*.css" ], options : { assetDirs: [ '<%= site.destination %>', './css' ] } },
. cache-breaker
这个任务也是清除静态文件的浏览器缓存,相对usemin简单些。但是,cache-breaker只替换head标签中的url,不替换body中的链接。一般都会有置底加载的JS文件,这个任务就不太适用。
// Turn these :
<script src="/js/dist/combined.min.js"></script>
<link href="/css/style.css"></link>
// Into these :
<script src="/js/dist/combined.min.js?rel=123456"></script>
<link href="/css/style.css?rel=123456"></link>
cachebreaker: { kuidoc_js: { asset_url : '<%= kuidoc_js %>', files: { src : './_kui/*.html' } }, kuidoc_css: { asset_url : '<%= kuidoc_css %>', files: { src : './_kui/*.html' } } },
. cacheBust
这个任务也是清除静态文件的浏览器缓存,支持的静态文件格式有:CSS, JavaScript, images 和 favicons。这个任务会忽略远程静态文件,因为一般这些远程文件是存储在CDN上的静态文件通常是很稳定的库文件,比如jQuery、Bootstrap...它们的url通常会有个版本标志,通过这个标识符来避免浏览器缓存。你的页面最好引用用这些标准的url,保证浏览器缓存的命中率。304总是比200快。也就是,类似以下的url会被忽略:
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
没有采用这个任务的理由:
1、项目中css和js独立部署和引用,静态文件引入的是绝对地址,我们也希望能够清除缓存,这个任务不适用。
2、cacheBust针对html文件中的静态文件寻址是相对于Grunt.js文件的,这就要求html文件和Grunt.js在同一个文件夹中。
3、任务执行后有漏掉的css。
JS任务
. Uglify
这个任务一直在更新增强:
1、压缩我们的JavaScript文件;
2、Beautify反压缩JS文件;
3、可以用它给多文件生成source-map。
注意:Angular压缩的时候会将$scope
变成 a
,压缩前要先执行ng-min任务。
uglify: { controller: { options: { banner: '<%= banner %>', report: 'min', // for Angular keyword $scope mangle: false, // except: ['jQuery', 'Angular', '$scope'], // for source map sourceMapRoot: '<%= doc_dir %>', sourceMap: '<%= doc_dir %>/js/kui-controller.min.js.map', sourceMapUrl: '<%= doc_dir %>/js/kui-controller.min.js.map' }, src: '<%= doc_dir %>/js/kui-controller.ngmin.js', dest: '<%= doc_dir %>/js/kui-controller.min.js' } },
. ng-min
AngularJS控制器构造函数通常简写成
$var SomeCtrl = function($scope, $element) {}
$scope, $element 是参数,但换个名字代码就不能正常运行了。也就是AngularJS是通过控制器构造函数的参数名字来推断依赖服务名称。所以如果你要压缩控制器的JS代码,它所有的参数也同时会被压缩,这时候依赖注入系统就不能正确的识别出服务了。
为了克服压缩引起的问题,
第一种方法是在控制器函数里面给$inject属性赋值一个依赖服务标识符的数组。
第二种方法使用Javascript数组方式构造控制器:把要注入的服务放到一个字符串数组(代表依赖的名字)里,数组最后一个元素是控制器的方法函数,就像AMD声明一样,写成
$var SomeCtrl = ['$scope', '$element', function(s, e) {}
ng-min采用的是第二种方法,来避免压缩引起的依赖注入系统不能识别服务问题。
ngmin: { controllers: { src: ['<%= doc_dir %>/js/kui-controller.js'], dest: '<%= doc_dir %>/js/kui-controller.ngmin.js' } },
. sloc
计算代码行。sloc: { options: { reportType: 'json', reportPath: '<%= doc_dir %>/sloc-v<%= pkg.version %>.json', }, files: { './': '<%= doc_dir %>/js/kui-controller.js', './': [ 'kui.js' ] } },
CSS任务
. grunt-recess
包括less编译和css压缩。
recess: { options: { compile: true, banner: '<%= banner %>' }, kui: { src: ['./less/kui.less'], dest: './css/kui.css' }, kui_min: { options: { compress: true }, src: ['./less/kui.less'], dest: '<%= kui_css %>' } },
. Less
less编译
. cssmin
css压缩(有时压缩后浏览器无法载入)
验证和测试任务
. jshint
检查js代码错误。通过.jshintrc 来定义检测项。
jshint: { //JSHint (http://www.jshint.com/docs/options/) options: { jshintrc: 'js/.jshintrc', globals: { jquery: true } }, kui: { src: ['<%= js_dir %>/modal.confirm.js'] }, controller: { src: ['<%= doc_dir %>/js/controller/*.js'] }, kuidoc: { src: ['<%= doc_dir %>/js/<%= pkg.name %>.min.js', '<%= doc_dir %>/js/<%= pkg.name %>.js'] } },
{ /* https://gist.github.com/haschek/2595796 */ "asi" : true, // Tolerate Automatic Semicolon Insertion (no semicolons). "boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. "browser" : true, // Standard browser globals e.g. `window`, `document`. "curly" : false, // Require {} for every new block or scope. "debug" : true, // Allow debugger statements e.g. browser breakpoints. "devel" : true, // Allow development statements e.g. `console.log();`. "eqeqeq" : false, // true: Require triple equals (===) for comparison "eqnull" : true, // true: Tolerate use of `== null` "expr" : true, // Tolerate `ExpressionStatement` as Programs. "laxbreak" : true, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. "laxcomma" : true, // Suppress warnings about comma-first coding style. "validthis": true, // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function. }
. html-validation
检查HTMlL。
options.relaxerror定义需要忽略的报错,可以基于正则表达式匹配。比如,AngularJS中需要忽略HTML标签中的“ng-”开头的属性: 'Attribute ng-[a-z]+ not allowed on element [a-z]+ at this point.'这个配置项非常有用。
validation: { options: { reset: true, relaxerror: [ 'Bad value X-UA-Compatible for attribute http-equiv on element meta.', 'Element link is missing one or more of the following attributes: itemprop, property, rel.', 'Attribute srcset not allowed on element img at this point.', 'Attribute ng-[a-z]+ not allowed on element [a-z]+ at this point.', 'document type does not allow element [a-z]+ here', '& did not start a character reference. *', 'Element xmp not allowed as child of element div in this context. *' ] }, files: { src: ["_kui/*.html"] } },
. uncss
检测HTML中没有使用到的css,并去除多余的css。
uncss: { dist: { files: { 'dist/css/tidy.css': ['app/index.html','app/about.html'] } } },
. jasmine
前端单元测试
基本grunt任务
. clean
清除文件,每次编译,需要清除旧文件。
. concat
合并文件。注意:如果concat后的文件不清除,会不停的在该文件内容的最前concat内容。
. copy
拷贝代码到build路径。
. watch
使用grunt watch
来运行这个任务。监视特定目录中的变化,然后把代码编译/打包。
注意:clean任务第一个执行,copy任务最后执行。
安装命令
//安装Grunt的命令行接口(CLI) npm install -g grunt-cli npm install grunt-contrib-clean --save-dev npm install grunt-contrib-copy --save-dev npm install grunt-contrib-concat --save-dev npm install grunt-contrib-uglify --save-dev npm install grunt-contrib-jshint --save-dev npm install grunt-recess --save-dev npm install grunt-html-validation --save-dev npm install grunt-contrib-watch --save-dev npm install grunt-cache-bust --save-dev npm install grunt-cache-breaker --save-dev npm install grunt-jekyll --save-dev npm install grunt-ngmin --save-dev npm install grunt-sloc --save-dev npm install grunt-contrib-less --save-dev npm install grunt-contrib-cssmin --save-dev npm install grunt-contrib-jasmine --save-dev
加载所需要的Grunt插件
grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-ngmin'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-recess'); grunt.loadNpmTasks('grunt-html-validation'); grunt.loadNpmTasks('grunt-jekyll'); grunt.loadNpmTasks('grunt-cache-breaker'); grunt.loadNpmTasks('grunt-rev'); grunt.loadNpmTasks('grunt-usemin'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-sloc');
http://24ways.org/2013/grunt-is-not-weird-and-hard/
http://mikemclin.net/configuring-package-json-and-gruntfile-js/
Semantic Versioning Specification http://semver.org
NPM | package.json https://npmjs.org/doc/json.html
相关推荐
### 常用Grunt插件 在本Demo中,我们可能会使用到以下插件: 1. `grunt-contrib-concat`:用于合并多个文件为一个文件。 2. `grunt-contrib-uglify`:JavaScript代码压缩。 3. `grunt-contrib-watch`:监听文件...
常用 Grunt 插件 - `grunt-contrib-concat`:用于合并多个 JavaScript 或 CSS 文件。 - `grunt-contrib-uglify`:JavaScript 文件的压缩和混淆。 - `grunt-contrib-cssmin`:CSS 文件的压缩。 - `grunt-contrib-...
5. **运行Grunt任务** 在配置完成后,可以通过命令行执行`grunt`或特定任务(如`grunt concat`,`grunt uglify`),Grunt会按照配置自动执行相关任务。 6. **最佳实践** - 使用`Grunt.watch`监听文件变化,自动...
- **环境配置管理**:根据不同环境(开发、测试、生产)配置不同的Grunt任务,实现环境间的平滑切换。 #### 六、高级用法 - **多环境支持**:在`Gruntfile.js`中可以通过条件判断实现不同环境下的任务配置。 - **...
【Brackets-Grunt:在Brackets中管理与运行Grunt任务】 Brackets-Grunt是一款专门为Adobe Brackets设计的扩展程序,它使得开发者能够直接在Brackets的环境中查看和执行Grunt任务,极大地提高了前端开发的工作效率。...
【load-grunt-configs】是一个前端开发中常用的开源库,其主要功能是帮助开发者更方便地管理和组织Grunt任务配置。Grunt,作为JavaScript的世界里的一款自动化工具,常常被用来执行构建、测试、压缩等任务。然而,当...
通过在Gruntfile.js中配置该插件,可以指定Elasticsearch实例的URL,以及其他相关参数,然后在Grunt任务中运行该插件,启动Elasticsearch Head。 在压缩包文件"node_modules"中,包含了Grunt插件和其他依赖项。`...
JavaScript构建工具Grunt是开发者们在进行前端项目开发时常用的一款自动化工具,它极大地提高了工作效率,简化了诸如编译、测试、压缩、合并等常见任务的执行过程。Grunt是基于Node.js平台的,利用npm(Node包管理器...
而grunt-contrib则是Grunt的官方贡献者团队维护的一系列常用任务插件的集合,覆盖了前端开发中的多个关键环节。 首先,我们需要了解什么是Grunt。Grunt是基于Node.js构建的,它通过JSON格式的配置文件(Gruntfile....
2. 常用grunt插件:如grunt-contrib-concat用于文件合并,grunt-contrib-uglify用于JavaScript代码压缩,grunt-contrib-watch用于实时监控文件变化并自动执行任务。 3. 自定义任务:grunt允许开发者创建自定义任务,...
### Grunt任务配置 在`Gruntfile.js`中,我们通过`grunt.initConfig()`方法定义任务配置。例如,要配置一个简单的测试任务,我们可以引入`grunt-contrib-jasmine`插件来执行 Jasmine 测试: ```javascript module....
在`Gruntfile.js`中,我们可以看到各种Grunt任务的配置,包括任务的定义、依赖关系和执行逻辑。Grunt同样支持各种插件,用于处理不同的构建需求。 与Gulp相比,Grunt的配置方式可能对初学者更友好,因为它是显式...
`grunt-cola` 是一款前端开发中常用的开源构建工具,它是基于 `Grunt.js` 的一个扩展插件,名为 "咕噜可乐" 或 "colac"。这个工具旨在简化前端项目的构建流程,包括自动化任务如编译、压缩、合并代码,以及资源管理...
Grunt是一个基于任务的构建工具,适用于JavaScript项目。它允许开发者定义一系列任务,如编译、压缩、测试等,然后在需要时自动执行这些任务。"grunt-travis-matrix"作为Grunt插件,可以方便地将Travis CI的矩阵构建...
"grunt-starter"项目,旨在为初学者提供一个预配置的Gruntfile.js和常用的Grunt插件集合,帮助开发者快速搭建起自己的JavaScript开发环境。 Gruntfile.js是Grunt的核心,它是Grunt的任务配置文件。通过这个文件,...
`watch` 是 Grunt 中的一个常用插件,它可以监控文件变化,一旦检测到文件改动,就会自动执行相关的任务。任务分类意味着 Gruntfile.js 被组织得更加清晰,不同的任务被分到不同的类别下,便于管理和维护。 - v...
通过Brackets Tasks,我们可以把常用的构建自动化工具——Grunt和Gulp无缝地接入到Brackets中,实现任务的可视化管理。 Grunt和Gulp是两个非常流行的JavaScript构建工具,它们用于自动化项目构建过程,如编译Sass或...
"grunt-website-boilerplate" 提供的这个模板可能还包含了其他常用的 Grunt 插件和配置,以满足不同项目需求。不过,描述中提到的“禁用”可能意味着某些默认任务或配置已被关闭,这可能是为了适应特定项目的需求...