grunt的学习和使用
目前正在编写公司的部分组件,可能一个组件会包含很多js和css,为了项目上使用方便,应该压缩成一个js库,以供开发者使用,同时也可以减少很多http请求,提高页面访问速度。基于此,学习了grunt自动化构建工具。学习文章:http://developer.51cto.com/art/201506/479127.htm。不过我根据自己的实际情况,有些东西做了一些改动,同时记录下来,后面也会用到。下面单刀直入,直接讲怎么用:
1、安装nodejs。安装过程略。下载路径:https://nodejs.org/en/ 。检查安装是否成功:打开cmd,输入node -v,如果出现以下界面,表示安装成功。
2、安装grunt-cli。打开cmd、输入npm install -g grunt-cli。出现以下信息,表示安装成功。
3、打开项目目录 ,在项目的根目录下新建配置文件:Gruntfile.js和package.json两个文件。其中package.json文件中先写入以下内容:
{ "name": "vetech.select", "version": "1.0", "devDependencies": { } }
4、安装grunt:cmd切换到项目的根目录下,并输入:npm install grunt -save-dev。工程目录下有以下目录表示安装成功。
5、配置Gruntfile.js文件:
//包装函数 module.exports = function(grunt){ //任务配置,所有插件的配置信息 grunt.initConfig({ //获取package.json的信息 pkg:grunt.file.readJSON("package.json") }); //告诉grunt当我们在终端输入grunt时,需要做些什么(有先后顺序) grunt.registerTask("default",[]); };
6、cmd中执行grunt命令,看是否配置成功。
7、安装插件:由于在项目中,并不是每个js都是独立的文件,有时候每个js可能会存在依赖关系。所以在安装插件的时候,先安装合并插件、再安装校验插件、压缩插件,最后安装自动化构建插件。所有的插件安装必须要切换到项目的根目录下执行才行,另外,每次安装一个插件最好是执行一下grunt命令,看是否安装和配置成功。
- 合并插件:https://www.npmjs.com/package/grunt-contrib-concat
- 安装命令:npm install grunt-contrib-concat --save-dev
- Gruntfile.js配置:
1 //包装函数 2 module.exports = function(grunt){ 3 //任务配置,所有插件的配置信息 4 grunt.initConfig({ 5 //获取package.json的信息 6 pkg:grunt.file.readJSON("package.json"), 7 //合并插件: 8 concat:{ 9 js:{ 10 src:["js/mxUtil.js","js/MultSelect.js","js/RadioSelect.js"], 11 dest:"build/debug/<%= pkg.name%>-<%=pkg.version%>.debug.js" 12 }, 13 css:{ 14 src:["css/style.css","css/radio.css"], 15 dest:"build/debug/<%=pkg.name%>-<%=pkg.version%>.debug.css" 16 } 17 } 18 19 }); 20 grunt.loadNpmTasks("grunt-contrib-concat"); 21 22 //告诉grunt当我们在终端输入grunt时,需要做些什么(有先后顺序) 23 grunt.registerTask("default",["concat"]); 24 };
-
说明: 在配置dest路径的时候,在build目录下新建了一个debug文件夹,所有的js和css合并以后都放在这里,这样做的好处有有两个:1、在校验和压缩的时候,只需要校验和压缩这两个文件即可;2、对于项目上对组件使用可能出问题,可以直接用合并的js作为调试文件来找出问题原因。
- js校验插件:https://www.npmjs.com/package/grunt-contrib-jshint
- 安装命令:npm install grunt-contrib-jshint --save-dev
- Gruntfile.js配置:
1 //包装函数 2 module.exports = function(grunt){ 3 //任务配置,所有插件的配置信息 4 grunt.initConfig({ 5 //获取package.json的信息 6 pkg:grunt.file.readJSON("package.json"), 7 //合并插件: 8 concat:{ 9 js:{ 10 src:["js/mxUtil.js","js/MultSelect.js","js/RadioSelect.js"], 11 dest:"build/debug/<%= pkg.name%>-<%=pkg.version%>.debug.js" 12 }, 13 css:{ 14 src:["css/style.css","css/radio.css"], 15 dest:"build/debug/<%=pkg.name%>-<%=pkg.version%>.debug.css" 16 } 17 }, 18 //js语法校验插件 19 jshint:{ 20 build:["Gruntfile.js","build/debug/<%=pkg.name%>.debug.js"], 21 options:{ 22 jshintrc:".jshintrc" 23 } 24 } 25 }); 26 grunt.loadNpmTasks("grunt-contrib-concat"); 27 grunt.loadNpmTasks("grunt-contrib-jshint"); 28 //告诉grunt当我们在终端输入grunt时,需要做些什么(有先后顺序) 29 grunt.registerTask("default",["concat","jshint"]); 30 };
备注:在js校验的时候,像JQuery、$、angular等等,校验不会通过,此时需要预先定义,参考文章:http://stackoverflow.com/questions/20837139/jshint-r10-angular-is-not-defined。另外,在校验的时候,还需要在Gruntfile.js文件的同级目录下新建一个.jshintrc文件,文件中编写要校验的规则。格式如下,规则参考:http://my.oschina.net/wjj328938669/blog/637433?p=1
{ "boss":false, "curly":false, "eqeqeq":false, "eqnull":true, "expr":true, "immed":true, "newcap":true, "noempty":true, "noarg":true, "undef":true, "regexp":true, "browser":true, "devel":true, "node":true, "predef": ["ActiveXObject"] }
- css校验插件:https://www.npmjs.com/package/grunt-contrib-csslint
- 安装命令:npm install grunt-contrib-csslint --save-dev
- Gruntfile.js配置:
1 //包装函数 2 module.exports = function(grunt){ 3 //任务配置,所有插件的配置信息 4 grunt.initConfig({ 5 //获取package.json的信息 6 pkg:grunt.file.readJSON("package.json"), 7 //合并插件: 8 concat:{ 9 js:{ 10 src:["js/mxUtil.js","js/MultSelect.js","js/RadioSelect.js"], 11 dest:"build/debug/<%= pkg.name%>-<%=pkg.version%>.debug.js" 12 }, 13 css:{ 14 src:["css/style.css","css/radio.css"], 15 dest:"build/debug/<%=pkg.name%>-<%=pkg.version%>.debug.css" 16 } 17 }, 18 //js语法校验插件 19 jshint:{ 20 build:["Gruntfile.js","build/debug/<%=pkg.name%>.debug.js"], 21 options:{ 22 jshintrc:".jshintrc" 23 } 24 }, 25 //css语法校验 26 csslint:{ 27 build:["build/debug/<%=pkg.name%>.debug.css"], 28 options:{ 29 csslintrc:".csslintrc" 30 } 31 } 32 }); 33 grunt.loadNpmTasks("grunt-contrib-concat"); 34 grunt.loadNpmTasks("grunt-contrib-jshint"); 35 grunt.loadNpmTasks("grunt-contrib-csslint"); 36 37 //告诉grunt当我们在终端输入grunt时,需要做些什么(有先后顺序) 38 grunt.registerTask("default",["concat","jshint","csslint"]); 39 };
-
- 备注: css校验插件也需要一个.csslintrc文件,同样是在Gruntfile.js的同级目录下。格式如下,配置参考:https://atom.io/packages/csslint
{ "adjoining-classes":false, "box-sizing":false, "box-model":false, "compatible-vendor-prefixes":false, "floats":false, "font-sizes":false, "gradinents":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 }
- 备注: css校验插件也需要一个.csslintrc文件,同样是在Gruntfile.js的同级目录下。格式如下,配置参考:https://atom.io/packages/csslint
- JS压缩插件:https://www.npmjs.com/package/grunt-contrib-uglify
- 安装命令:npm install grunt-contrib-uglify --save-dev
- Gruntfile.js配置:
1 //包装函数 2 module.exports = function(grunt){ 3 //任务配置,所有插件的配置信息 4 grunt.initConfig({ 5 //获取package.json的信息 6 pkg:grunt.file.readJSON("package.json"), 7 //合并插件: 8 concat:{ 9 js:{ 10 src:["js/mxUtil.js","js/MultSelect.js","js/RadioSelect.js"], 11 dest:"build/debug/<%= pkg.name%>-<%=pkg.version%>.debug.js" 12 }, 13 css:{ 14 src:["css/style.css","css/radio.css"], 15 dest:"build/debug/<%=pkg.name%>-<%=pkg.version%>.debug.css" 16 } 17 }, 18 //js语法校验插件 19 jshint:{ 20 build:["Gruntfile.js","build/debug/<%=pkg.name%>.debug.js"], 21 options:{ 22 jshintrc:".jshintrc" 23 } 24 }, 25 //css语法校验 26 csslint:{ 27 build:["build/debug/<%=pkg.name%>.debug.css"], 28 options:{ 29 csslintrc:".csslintrc" 30 } 31 }, 32 //js压缩 33 uglify:{ 34 options:{ 35 stripBanners:true, 36 banner:'/*! <%=pkg.name%>-<%=pkg.version%>.js <%=grunt.template.today("yyyy-mm-dd")%> */\n' 37 }, 38 build:{ 39 mangle:true, //变量名混淆 40 src:"build/debug/*.js", 41 dest:"build/app/<%=pkg.name%>-<%=pkg.version%>.min.js" 42 } 43 } 44 }); 45 grunt.loadNpmTasks("grunt-contrib-concat"); 46 grunt.loadNpmTasks("grunt-contrib-jshint"); 47 grunt.loadNpmTasks("grunt-contrib-csslint"); 48 grunt.loadNpmTasks("grunt-contrib-uglify"); 49 50 //告诉grunt当我们在终端输入grunt时,需要做些什么(有先后顺序) 51 grunt.registerTask("default",["concat","jshint","csslint","uglify"]); 52 };
- css压缩插件:https://www.npmjs.com/package/grunt-contrib-cssmin
- 安装命令:npm install grunt-contrib-cssmin --save-dev
- Gruntfile.js配置:
1 //包装函数 2 module.exports = function(grunt){ 3 //任务配置,所有插件的配置信息 4 grunt.initConfig({ 5 //获取package.json的信息 6 pkg:grunt.file.readJSON("package.json"), 7 //合并插件: 8 concat:{ 9 js:{ 10 src:["js/mxUtil.js","js/MultSelect.js","js/RadioSelect.js"], 11 dest:"build/debug/<%= pkg.name%>-<%=pkg.version%>.debug.js" 12 }, 13 css:{ 14 src:["css/style.css","css/radio.css"], 15 dest:"build/debug/<%=pkg.name%>-<%=pkg.version%>.debug.css" 16 } 17 }, 18 //js语法校验插件 19 jshint:{ 20 build:["Gruntfile.js","build/debug/<%=pkg.name%>.debug.js"], 21 options:{ 22 jshintrc:".jshintrc" 23 } 24 }, 25 //css语法校验 26 csslint:{ 27 build:["build/debug/<%=pkg.name%>.debug.css"], 28 options:{ 29 csslintrc:".csslintrc" 30 } 31 }, 32 //js压缩 33 uglify:{ 34 options:{ 35 stripBanners:true, 36 banner:'/*! <%=pkg.name%>-<%=pkg.version%>.js <%=grunt.template.today("yyyy-mm-dd")%> */\n' 37 }, 38 build:{ 39 mangle:true, //变量名混淆 40 src:"build/debug/*.js", 41 dest:"build/app/<%=pkg.name%>-<%=pkg.version%>.min.js" 42 } 43 }, 44 //css压缩 45 cssmin:{ 46 options:{ 47 stripBanners:true, 48 banner:'/*! <%=pkg.name%>-<%=pkg.version%>.css <%=grunt.template.today("yyyy-mm-dd")%> */\n' 49 }, 50 build:{ 51 src:"build/debug/*.css", 52 dest:"build/app/<%=pkg.name%>-<%=pkg.version%>.min.css" 53 } 54 } 55 56 }); 57 grunt.loadNpmTasks("grunt-contrib-concat"); 58 grunt.loadNpmTasks("grunt-contrib-jshint"); 59 grunt.loadNpmTasks("grunt-contrib-csslint"); 60 grunt.loadNpmTasks("grunt-contrib-uglify"); 61 grunt.loadNpmTasks("grunt-contrib-cssmin"); 62 63 //告诉grunt当我们在终端输入grunt时,需要做些什么(有先后顺序) 64 grunt.registerTask("default",["concat","jshint","csslint","uglify","cssmin"]); 65 };
- 自动化构建:https://www.npmjs.com/package/grunt-contrib-watch
- 安装命令:npm install grunt-contrib-watch --save-dev
- Gruntfile.js配置:
1 //包装函数 2 module.exports = function(grunt){ 3 //任务配置,所有插件的配置信息 4 grunt.initConfig({ 5 //获取package.json的信息 6 pkg:grunt.file.readJSON("package.json"), 7 //合并插件: 8 concat:{ 9 js:{ 10 src:["js/mxUtil.js","js/MultSelect.js","js/RadioSelect.js"], 11 dest:"build/debug/<%= pkg.name%>-<%=pkg.version%>.debug.js" 12 }, 13 css:{ 14 src:["css/style.css","css/radio.css"], 15 dest:"build/debug/<%=pkg.name%>-<%=pkg.version%>.debug.css" 16 } 17 }, 18 //js语法校验插件 19 jshint:{ 20 build:["Gruntfile.js","build/debug/<%=pkg.name%>.debug.js"], 21 options:{ 22 jshintrc:".jshintrc" 23 } 24 }, 25 //css语法校验 26 csslint:{ 27 build:["build/debug/<%=pkg.name%>.debug.css"], 28 options:{ 29 csslintrc:".csslintrc" 30 } 31 }, 32 //js压缩 33 uglify:{ 34 options:{ 35 stripBanners:true, 36 banner:'/*! <%=pkg.name%>-<%=pkg.version%>.js <%=grunt.template.today("yyyy-mm-dd")%> */\n' 37 }, 38 build:{ 39 mangle:true, //变量名混淆 40 src:"build/debug/*.js", 41 dest:"build/app/<%=pkg.name%>-<%=pkg.version%>.min.js" 42 } 43 }, 44 //css压缩 45 cssmin:{ 46 options:{ 47 stripBanners:true, 48 banner:'/*! <%=pkg.name%>-<%=pkg.version%>.css <%=grunt.template.today("yyyy-mm-dd")%> */\n' 49 }, 50 build:{ 51 src:"build/debug/*.css", 52 dest:"build/app/<%=pkg.name%>-<%=pkg.version%>.min.css" 53 } 54 }, 55 //自动化构建 56 watch:{ 57 build:{ 58 files:["Gruntfile.js","js/*.js","css/*.css"], 59 tasks:["concat","jshint","csslint","uglify","cssmin"], 60 options:{spawn:false} 61 } 62 } 63 64 }); 65 grunt.loadNpmTasks("grunt-contrib-concat"); 66 grunt.loadNpmTasks("grunt-contrib-jshint"); 67 grunt.loadNpmTasks("grunt-contrib-csslint"); 68 grunt.loadNpmTasks("grunt-contrib-uglify"); 69 grunt.loadNpmTasks("grunt-contrib-cssmin"); 70 grunt.loadNpmTasks("grunt-contrib-watch"); 71 72 //告诉grunt当我们在终端输入grunt时,需要做些什么(有先后顺序) 73 grunt.registerTask("default",["concat","jshint","csslint","uglify","cssmin","watch"]); 74 };
执行完以上的所有操作,基本上可以满足js和css的校验、合并和压缩。最后执行grunt,会发现根据Gruntfile.js配置的,生成相应的文件,前提是js和css不会存在错误。下图是执行grunt以后生成的文件:
最后,直接把app中的文件拷贝到项目中去使用即可。对于watch插件,指定监听哪些文件,一旦文件发生变化,会重新构建。如果有新的项目需要自动化构建,那么只需要将Gruntfile.js、package.json、两个以.开头的配置文件拷贝过去,在根目录下执行:npm install,一次性安装好所有的插件。然后修改Gruntfile.js以满足当前项目需要。