Grunt入门教程
引入: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入门教程的更多相关文章
- Grunt 入门
转自:http://user.qzone.qq.com/174629171/blog/1404433906 Grunt被定义为:the javascript task runner. 什么算是Java ...
- gulp详细入门教程
本文链接:http://www.ydcss.com/archives/18 gulp详细入门教程 简介: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优 ...
- gulp的使用以及Gulp新手入门教程
Gulp新手入门教程 原文 http://w3ctrain.com/2015/12/22/gulp-for-beginners/ Gulp 是一个自动化工具,前端开发者可以使用它来处理常见任务: 搭 ...
- 观看杨老师(杨旭)Asp.Net Core MVC入门教程记录
观看杨老师(杨旭)Asp.Net Core MVC入门教程记录 ASP.NET Core MVC入门 Asp.Net Core启动和配置 Program类,Main方法 Startup类 依赖注入,I ...
- grunt小教程
本人的博客写了grunt的小教程,从零开始,一步一步的通过例子讲解,希望喜欢的同学给我的github上加颗星,谢谢! github地址: https://github.com/manlili/grun ...
- npm 与 package.json 快速入门教程
npm 与 package.json 快速入门教程 2017年08月02日 19:16:20 阅读数:33887 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解 ...
- [转载]npm 与 package.json 快速入门教程
npm 与 package.json 快速入门教程 2017-08-02 19:16:20 拭心 阅读数 78648更多 分类专栏: 学学前端 版权声明:本文为博主原创文章,遵循CC 4.0 BY ...
- mui初级入门教程(六)— 模板页面实现原理及多端适配指南
文章来源:小青年原创发布时间:2016-07-26关键词:mui,webview,template,os,多端适配转载需标注本文原始地址: http://zhaomenghuan.github.io. ...
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
随机推荐
- javascript中对象在OOP方面的一些知识(主要是prototype和__proto__相关)
在ES6的Class到来之前,先总结下个人对js中prototype属性的理解. 1.构造函数(大写函数名 this 无return) 2.原型对象(函数.prototype) 3.实例对象( ...
- a链接中套a链接
<a href="baidu.com"> <div> <div class="title">百度</div> & ...
- Redis学习笔记~实现消息队列比MSMQ更方便
什么是队列:简单的说就是数据存储到一个空间里(可以是内存,也可以是物理文件),先存储的数据对象,先被取出来,这与堆栈正好相反,消息队列也是这样,将可能出现高并发的数据进行队列存储,并按着入队的顺序依次 ...
- Spring init-method和destroy-method 的使用
Spring init-method和destroy-method 的使用 Spring 为了满足开发者在执行某方法之前或者在结束某个任务之前需要操作的一些业务,则提供了init-method和des ...
- hdu 1159, LCS, dynamic programming, recursive backtrack vs iterative backtrack vs incremental, C++ 分类: hdoj 2015-07-10 04:14 112人阅读 评论(0) 收藏
thanks prof. Abhiram Ranade for his vedio on Longest Common Subsequence 's back track search view in ...
- android 在使用studio 编写百度地图中遇到APP Scode码校验失败 问题
直接用打包出来的apk查看签名,具体如下: 1) 将apk修改后缀为 .zip文件后解压: 2) 进入解压后的META-INF目录,该目录下会存在文件CERT.RSA 3) 在该目录下打开cmd,输入 ...
- 启动Mysql服务提示Can’t connect to local MySQL server through socket的解决方法
启动Mysql服务常会提示下面错误: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/ ...
- 非Animal呢?为何不写个万用类
/*4.非Animal呢?为何不写个万用类 * 类Object是JAVA里多有类的源头/父类*/ import java.util.*; class Animalb{ String name; voi ...
- linux自动更新代码,打包发布
1.安装svn yum install subversion 2.安装 maven 下载:百度云盘地址为 http://pan.baidu.com/s/1nuKQGjv 解压 tar -zxvf ap ...
- OGG for DB2 i 12.2发布
2016-04-15 Oracle发布了GoldenGate for DB2 i 12.2.0.1.2,软件可以从OTN 或 eDelivery下载.这是第一个针对DB2 for i的12.2版本.此 ...