引入:grunt是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:

  • ① 压缩文件
  • ② 合并文件
  • ③ 简单语法检查

环境:grunt是基于nodejs运行的,所以需要有nodejs,在Nodejs中,安装grunt的命令行接口。

 npm install -g grunt-cli

将grunt命令植入系统路径。通过nodejs的require查找到安装的grunt,就能在任意目录下运行grunt项目了。

在一个简单的实例中,慢慢享受grunt给前端所带来的便捷与随心所欲。

新建项目的时候,增加两个文件,一个为:package.json;另一个为:Gruntfile.js。


package.json

这个文件用来存储npm模块的依赖项(比如我们的打包若是依赖requireJS的插件,这里就需要配置)
然后,我们会在里面配置一些不一样的信息,比如我们上面的file,这些数据都会放到package中
对于package的灵活配置。


Gruntfile

这个文件尤其关键,他一般干两件事情:
① 读取package信息
② 插件加载、注册任务,运行任务(grunt对外的接口全部写在这里面)

Gruntfile一般由四个部分组成
① 包装函数
这个包装函数没什么东西,意思就是我们所有的代码必须放到这个函数里面

module.exports = function (grunt) {
//你的代码
}

这个不用知道为什么,直接将代码放入即可

② 项目/任务配置
我们在Gruntfile一般第一个用到的就是initConfig方法配置依赖信息

pkg: grunt.file.readJSON('package.json')

这里的 grunt.file.readJSON就会将我们的配置文件读出,并且转换为json对象

然后我们在后面的地方就可以采用pkg.XXX的方式访问其中的数据了
值得注意的是这里使用的是underscore模板引擎,所以你在这里可以写很多东西

uglify是一个插件的,我们在package依赖项进行了配置,这个时候我们为系统配置了一个任务
uglify(压缩),他会干这几个事情:

① 在src中找到zepto进行压缩(具体名字在package中找到)
② 找到dest目录,没有就新建,然后将压缩文件搞进去
③ 在上面加几个描述语言

这个任务配置其实就是一个方法接口调用,按照规范来就好,暂时不予关注,内幕后期来
这里只是定义了相关参数,但是并未加载实际函数,所以后面马上就有一句:

grunt.loadNpmTasks('grunt-contrib-uglify');

用于加载相关插件

最后注册一个自定义任务(其实也是默认任务),所以我们下面的命令行是等效的:

grunt == grunt uglify

实例:

1 js压缩打包

package.json文件

 {
"name": "demo",
"file": "zepto",
"version": "0.1.0",
"description": "demo",
"license": "MIT",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.6.3",
"grunt-contrib-uglify": "~0.2.1",
"grunt-contrib-requirejs": "~0.4.1",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-clean": "~0.5.0",
"grunt-strip": "~0.2.1"
},
"dependencies": {
"express": "3.x"
}
}

1->1(一个文件打包压缩到另一个文件):

  module.exports = function (grunt) {
banner: '/*! <%= pkg.file %>Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: { src: 'build/js/<%=pkg.file %>.js',
dest: 'dist/js/<%= pkg.file %>.min.js'
}
}

N->1(N个文件打包压缩到一个文件):

 module.exports = function (grunt) {
banner: '/*! <%= pkg.file %>Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: ['build/js/<%=pkg.file %>.js','build/js/<%=pkg.file %>1.js'], dest: 'dist/js/<%= pkg.file %>.min.js'
}
}

N->N(通过my_target):

 module.exports = function (grunt) {
options: {
banner: '/*! <%= pkg.file %> Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
my_target : {
files : {
'dist/js/index.min.js':['build/js/index.js'],
'dist/js/index1.min.js':['build/js/index1.js'],
'dist/js/index2.min.js':['build/js/index1.js'],
'dist/js/index3.min.js':['build/js/index1.js']
}
}
}

2 less编译打包

N->N

     less : {
development: {
options: {
compress: true
},
files: {
"dist/css/index1.css":"build/less/index1.less",
"dist/css/index.css" : "build/less/index.less"
}
}
}

N->1(将build/less/下的两个文件编译合并到dist/css/目录下)

  module.exports = function (grunt) {
less : {
development: {
options: {
compress: false
},
files: {
"dist/css/index.css":["build/less/index1.less","build/less/index.less"]
}
}
}

开发模式与产品模式(唯一区别就是开发模式下,为了进行调试,尽量不压缩文件,而上线版本,最好将其进行压缩)代码表示将build/less/下的两个Less文件转化为dist/css/下的css文件,两者前者为未压缩版本。

 module.exports = function (grunt) {
less : {
development: {
options: {
compress: false
},
files: {
"dist/css/index.css":["build/less/index1.less","build/less/index.less"]
}
},
production: {
options: {
compress: true
},
files: {
"dist/css/index4.css":["build/less/index1.less","build/less/index.less"]
}
}
}

3 图片优化(将图片进行优化处理,并生成新的文件,存放在另一个文件夹中)这里表示,匹配build/img下面的所有以png,jpg,gif,svg,jpeg格式结尾的文件,并一一进行优化处理,然后将优化后的图片放在dist/img/目录下。

 image : {
dynamic : {
files:[{
expand:true,
cwd:'build/img/',
src:['**/*.{png,jpg,gif,svg,jpeg'],
dest:'dist/img/'
}]
}
}
});

4 js语法检查(按照自定义的标准,检测绑定的相关js文件是否有语法错误)

    jshint : {
options: {
jshintrc :'.jshintrc'
},
core: {
src:'dist/js/index.min.js'
},
demo: {
src:'dist/js/index1.min.js'
}
}

5 监听(watch):通过绑定所有的js文件及less文件,并时时监听文件内容的变化,当变化发生时,将重新编译、压缩、打包生成最新的文件。

  uglify: {
options: {
banner: '/*! <%= pkg.file %> Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build : {
src: 'build/js/index.js',
dest:'dist/js/index6.min.js'
}
},
watch: {
files: ["build/less/*.less","build/js/*.js"],
tasks: ["less", "uglify"]
},

6 清理文件(构建成功后,将不再需要的文件删除,比如图片优化之后,之前的图片就可以清理掉了)

   clean: {
build: ["build/img/*"]
},

7 css文件校验处理

   csslint: {
options: {
csslintrc: 'build/less/.csslintrc'
},
dist:[
'dist/css/index1.css',
]
}

8 链接Bootstrap HTML 并进行语法检查

  bootlint: {
options: {
relaxerror: ['W002','W003','W005','W007']
},
files: ['*.html']
},

9 构建HTML模板

 includes: {
build: {
src: ['*.html'], // Source files
dest: 'documentation/', // Destination directory
flatten: true,
cwd: 'documentation/build',
options: {
silent: true,
includePath: 'documentation/build/include'
}
}

其中css链接处理需要的.jshintrc文件如下:

 {
"adjoining-classes": false,
"box-sizing": false,
"box-model": false,
"compatible-vendor-prefixes": false,
"floats": false,
"font-sizes": false,
"gradients": false,
"important": false,
"known-properties": false,
"outline-none": false,
"qualified-headings": false,
"regex-selectors": false,
"shorthand": false,
"text-indent": false,
"unique-headings": false,
"universal-selector": false,
"unqualified-attributes": false,
"ids": false,
"fallback-colors": false,
"vendor-prefix": false,
"import": false
}

完整的Gruntfile.js文件如下:

 module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.file %> Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build : {
src: 'build/js/index.js',
dest:'dist/js/index6.min.js'
}
},
watch: {
files: ["build/less/*.less","build/js/*.js"],
tasks: ["less", "uglify","image","clean"]
},
concat: {
options: {
separator: ';'
},
dist: {
src:["build/less/index1.less","build/less/index.less"],
dest:"build/less/index3.less"
}
},
less : {
development: {
options: {
compress: false
},
files: {
"dist/css/index6.css":["build/less/index1.less","build/less/index.less"]
}
},
production: {
options: {
compress: true
},
files: {
"dist/css/index5.css":["build/less/index1.less","build/less/index.less"]
}
}
},
clean: {
build: ["build/img/*"]
},
uglify: {
options: {
mangle:true,
preserveComments:'some'
}
}, cssmin: {
compress: {
files: {
"dist/css/index.css": [
"build/less/index1.less",
"build/less/index.less"
]
}
}
}
image: {
dynamic: {
files: [{
expand: true,
cwd: 'build/img/',
src: ['**/*.{png,jpg,gif,svg,jpeg}'],
dest: 'dist/img/'
}]
}
},
csslint: {
options: {
csslintrc: 'build/less/.csslintrc'
},
dist:[
'dist/css/index1.css',
]
},
bootlint: {
options: {
relaxerror: ['W002','W003','W005','W007']
},
files: ['*.html']
},
includes: {
build: {
src: ['*.html'], // Source files
dest: 'documentation/', // Destination directory
flatten: true,
cwd: 'documentation/build',
options: {
silent: true,
includePath: 'documentation/build/include'
}
}
}
jshint : {
options: {
jshintrc :'.jshintrc'
},
core: {
src:'dist/js/index.min.js'
},
demo: {
src:'dist/js/index1.min.js'
}
}
}); grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-image');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-csslint');
grunt.loadNpmTasks('grunt-bootlint');
grunt.loadNpmTasks('grunt-includes');
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.registerTask('link', ['includes']);
grunt.registerTask('default', ['includes']);
// Linting task
//grunt.registerTask('lint', ['jshint', 'csslint', 'bootlint']); // The default task (running "grunt" in console) is "watch"
//grunt.registerTask('default', ['watch']);
}

完整的目录结构如下:

aaarticlea/png;base64,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" alt="" />

整项目代码下载:Qboooogle

Grunt入门教程的更多相关文章

  1. Grunt 入门

    转自:http://user.qzone.qq.com/174629171/blog/1404433906 Grunt被定义为:the javascript task runner. 什么算是Java ...

  2. gulp详细入门教程

    本文链接:http://www.ydcss.com/archives/18 gulp详细入门教程 简介: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优 ...

  3. gulp的使用以及Gulp新手入门教程

    Gulp新手入门教程 原文  http://w3ctrain.com/2015/12/22/gulp-for-beginners/ Gulp 是一个自动化工具,前端开发者可以使用它来处理常见任务: 搭 ...

  4. 观看杨老师(杨旭)Asp.Net Core MVC入门教程记录

    观看杨老师(杨旭)Asp.Net Core MVC入门教程记录 ASP.NET Core MVC入门 Asp.Net Core启动和配置 Program类,Main方法 Startup类 依赖注入,I ...

  5. grunt小教程

    本人的博客写了grunt的小教程,从零开始,一步一步的通过例子讲解,希望喜欢的同学给我的github上加颗星,谢谢! github地址: https://github.com/manlili/grun ...

  6. npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017年08月02日 19:16:20 阅读数:33887 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解 ...

  7. [转载]npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017-08-02 19:16:20 拭心 阅读数 78648更多 分类专栏: 学学前端   版权声明:本文为博主原创文章,遵循CC 4.0 BY ...

  8. mui初级入门教程(六)— 模板页面实现原理及多端适配指南

    文章来源:小青年原创发布时间:2016-07-26关键词:mui,webview,template,os,多端适配转载需标注本文原始地址: http://zhaomenghuan.github.io. ...

  9. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

随机推荐

  1. css中的一些属性解析

    1.inline-block 存在问题:inline-block的相互间距,元素之间会有一个左右2px的margin一样产生            请看中间的空隙. 为什么会产生这个空隙呢?? 怎么解 ...

  2. PHP弱类型需要特别注意的问题

    下面介绍的问题都已验证, 总结:字符数据比较==不比较类型,会将字符转数据,字符转数字(转换直到遇到一个非数字的字符.即使出现无法转换的字符串,intval()不会报错而是返回0).0e,0x开头的字 ...

  3. 【IE6双倍边距】-IE6双倍边距的bug

    效果 代码 CSS IE6双倍边距的bug body { margin: 0; padding: 0; } .div1 { width: 200px; height: 200px; backgroun ...

  4. ListView

    ListView:列表展示数据1.视图 - 在其右上方小箭头点击将视图改为Largelcon:或右键属性在外观View将其改为Details2.设置列头 - 在其右上方小箭头点击选择编辑列,然后添加列 ...

  5. 深入理解iOS开发中的BitCode功能

    前言 做iOS开发的朋友们都知道,目前最新的Xcode7,新建项目默认就打开了bitcode设置.而且大部分开发者都被这个突如其来的bitcode功能给坑过导致项目编译失败,而这些因为bitcode而 ...

  6. Fake chat script for website download

    Are you searching for free fake webchat script then you are at the right place go get download your ...

  7. Jquery做全选

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. oracle 查看锁死的表,锁死的进程

    select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_mode f ...

  9. iOS_TCP和UDP的详解

    TCP和UDP面试经常被问到,一些初学者也经常问我这种问题,由于TCP协议和UDP协议是基于三次“对话”,解释起来很费劲,所以在这里详细的描述一下自己对TCP协议和UDP协议的理解,如有不妥之处,望指 ...

  10. Groovy解析xml并且注入Project,TestSuite,TestCase级别的custom properties

    import com.eviware.soapui.support.GroovyUtils import groovy.util.XmlParser def groovyUtils = new Gro ...