grunt + bower

Grunt+Bower的简单应用

前言

     首先要感谢那些知名的不知名的前辈们,你们的成就是我们进步的基础。

    本文针对的读者是那些像之前的我一样刚刚了解Grunt和Bower这两个名字是什么,但还不知道究竟是干什么的,同样是以应用为主,已经会基本使用这些的就不需要看了,因为都是最基础的一些东西,同样如果您看了之后发现有什么不符合逻辑或常识的问题,或是有什么错误,我会非常期待您的指正。

1.安装nodeJS

    grunt以及其插件都是需要依赖nodejs来运行的,所以如果你的电脑中并没有安装,那么需要安装nodejs,安装过程极其简单,就是傻瓜式的下一步直到install即可

    nodejs官网:https://nodejs.org/en/

这是官网打开以后的图,我们这里安装左边的就可以了。

安装完成以后,win+r cmd  打开命令提示符窗口,输入node -v查看版本号,以验证nodejs是否安装成功



2.安装grunt-CLI

这里就与传统的安装软件方式不同了,以后安装的一些插件基本都是使用这样的方式安装的,所以先不用问这是什么东西,用的时间长了就明白是个什么东西了

首先使用nodejs的npm install方式安装grunt-CLI ,很简单,就是在命令行里输入npm install -g grunt-cli 然后回车键


分析一下这句安装命令分别代表什么:

npm install :nodejs的安装插件方式

-g:全局安装

grunt-cli:插件名

确保电脑联网且网足够快

如果安装成功的话会出现grunt-cli的目录结构,安装失败找出原因重新安装即可,成功后类似这样:

进行验证看是否安装成功:

命令行输入grunt 回车键,证明grunt-cli安装成功

grunt-cli到这里基本上就安装完成了,接下来建立一个自己的前端项目吧。


3.构建项目目录结构

这里可以1.自己先建立一个简单的进行练手,2.也可以学习以下yoman这类可以直接构建目录结构的工具(npm install -g yo),3.或者是参考一些优秀的前端工程目录结构。

这里用一个简单的例子做练手,更加方便练习,但如果想要更加专业化,还是参考上边2、3方法

在D盘或者你的任意目录下建立一个文件夹,我的是D:\1Project Workspace\New_Test_Project,然后在这个文件夹中建立需要的文件夹和文件

接下来要建立一个名叫package.json的文件,有两种建立方式:

1直接建立文本并保存为json文件,内容为:

[html]  view plain  copy
  1. {  
  2.   "name": "new_test_project",  
  3.   "version": "1.0.0",  
  4.   "description": "test",  
  5.   "main": "index.js",  
  6.   "directories": {  
  7.     "test": "test"  
  8.   },  
  9.   "scripts": {  
  10.     "test": "echo \"Error: no test specified\" && exit 1"  
  11.   },  
  12.   "author": "ds",  
  13.   "license": "ISC"  
  14. }  

其中左边的名称是不可以更改的,右边的一些相当于参数的东西是可以进行更改的。


2.(推荐)在当前也就是D:\1Project Workspace\New_Test_Project这个目录下shift+右键打开命令行,输入npm init,回车键然后按照所需信息一步一步填写下来,项目名必须都是小写字母,版本号、简介等都可以不填写,一路回车下来,最后输入yes,就会发现这个文件已经建立好了:


4.安装grunt

接下来就是正主grunt的安装了,这里首先介绍一下更改npm下载源的方法,网足够好的可以跳过4.1的步骤接着往下看

4.1将下载源从国外改到淘宝

由于国外网络受网络波动影响大,时常导致下载失败,所以我们的淘宝团队将这些国外的镜像到了国内。

官方:这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。

官方地址:https://npm.taobao.org/

执行:npm install cnpm -g --registry=https://registry.npm.taobao.org;  注意:安装完后最好查看其版本号cnpm -v或关闭命令提示符重新打开,安装完直接使用有可能会出现错误;

注:cnpm跟npm用法完全一致,只是在执行命令时将npm改为cnpm(以下操作将以cnpm代替npm)。

4.2正式安装

执行安装命令之前看一下4.1的最后一句话。

在刚才建立的项目目录中打开命令提示符,执行:cnpm install grunt --save-dev

命令分析:

cnpm install: npm方式安装,用淘宝数据源

grunt:我们要安装插件的名字

--save-dev: 在当前目录安装grunt的同时,顺便把grunt保存为这个目录的开发依赖项,执行后打开package.json后就可已发现新增加了开发依赖项grunt

小tips:这里的名字和--save-dev是可以更换的,不会影响到执行结果,以后类似的命令同样适用,例如本次命令用cnpm install --save-dev grunt 执行的效果是相同的


首次安装:会出现目录结构


如果目录中多了node_modules文件夹,说明安装成功了

这时打开package.json文件,就会发现多了一些代码

而其中devDependencies的意思就是

然后新建一个名叫Gruntfile.js的文件在项目根目录下,它的作用是用来将我们需要配置的任务(Task)写到里边去执行的,所以先建立一个空文件

 这里要注意的是Gruntfile.js的G是大写,其它小写

经过以上几个步骤,我们可以认为grunt已经安装成功了,并且分析以上提示:Task ‘default’ not found。 说明我们该配置任务(Task)了,也就是在Gruntfile.js文件中写一些任务

5.配置Gruntfile.js(写Task)

打开Gruntfile.js输入以下官方规定的信息,这个脚本文件的规范就是这样的,所以没有为什么。

看源码,我们已经读取了package.json文件中的信息

[javascript]  view plain  copy
  1. module.exports = function(grunt){  
  2.   
  3.         grunt.initConfig({  
  4.             pkg: grunt.file.readJSON('package.json'),  
  5.             //这里要写之后的任务  
  6.         });  
  7.   
  8.         //default任务,即默认任务,执行命令为grunt或grunt default  
  9.         grunt.registerTask('default',[]);  
  10.   
  11.   
  12.         //这是之后配置的稍复杂的任务,这里我们先注释掉,稍后解释。  
  13.         //grunt.registerTask('import',['wiredep']);  
  14.         //grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);  
  15.         //grunt.registerTask('start',['connect','watch:start']);  
  16. };  
这里我们配置好了一个叫default(默认)的任务,它的任务列表,也就是右边的数组是空的,所以它可以启动但是不执行什么任务,这里我们执行这个任务的方式就是在命令提示符中输入 grunt  grunt default ,可以得到如下结果

同时我们再回去看一眼源代码,其它注释掉但有内容的执行方式分别是:grunt import ; grunt package ; grunt start。而其后边的数组中就是它依次要去执行的任务,那这些任务是如何配置的呢,接下来就一一介绍

6.写Task(grunt常用插件介绍)

这里要用到的就是grunt的插件了,这些插件都是从官网被审核后才能上架下载的,当然我们不需要去官网再艾格寻找下载,用我们的npm方式安装即可,但有兴趣的依然可以去官网看一眼

官方地址:http://www.gruntjs.net/plugins

插件分为两类。第一类是grunt团队贡献的插件,这些插件的名字前面都带有“contrib-”前缀,而且在插件列表中有星号标注。第二类是第三方提供的插件,不带有这两个特征。

并不是所有的插件都需要被用到,这里我们只去介绍一些我们用到的,常用的,并且每个插件配置的不同,其用法也不尽相同:

  • grunt-contrib-uglify——压缩javascript代码
  • grunt-contrib-jshint——javascript语法错误检查
  • grunt-contrib-watch——实时监控文件变化、调用相应的任务重新执行
  • grunt-wiredep——bower+grunt-wiredep依赖库自动注入(自动将bower下载的包导入html中)
  • grunt-contrib-connect——可配置一个web server服务器
  • grunt-usemin——根据注释替换到 CSS/JS 等资源引用(将原本引用的js、css自动改成发布版本的合并后的js、css)
  • grunt-contrib-copy——复制文件,从一个文件夹复制到另一个文件夹
  • grunt-contrib-concat——合并多个文件的代码到一个文件中(合并js,css)

接下来会大致讲解以下这些插件的用法,但不会详细介绍,只是应用,官网中还有许多更加优秀实用的插件,可以自行查找使用

先从应用的角度来看,我们先讲connect插件和watch插件,有了这两个之后,我们的前端开发就可以这边保存,浏览器中自动刷新看效果了

6.1grunt-contrib-connec

这个插件的作用是配置一个web server服务器,这样我们的前端用记事本都能开发了,这里推荐用IDE:WebStorm开发前端,因为它可以将命令提示符和grunt集成到开发工具中,用起来很方便,这里不细说了,以下为配置详情:

安装方法:命令提示符输入 cnpm install grunt-contrib-connect --save-dev


同以前一样,我们将这个配置保存到我们的package.json中


安装完成,下面介绍用法:打开Gruntfile.js修改一些配置

[javascript]  view plain  copy
  1. module.exports = function(grunt){  
  2.   
  3.      // LiveReload的默认端口号,你也可以改成你想要的端口号  
  4.     var lrPort = 35729;  
  5.     var serveStatic = require('serve-static');  
  6.     var serveIndex = require('serve-index')  
  7.      // 使用connect-livereload模块,生成一个与LiveReload脚本  
  8.      // <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>  
  9.      var lrSnippet = require('connect-livereload')({ port: lrPort });  
  10.      // 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件  
  11.     var lrMiddleware = function(connect, options, middlwares) {  
  12.       return [  
  13.         lrSnippet,  
  14.         // 静态文件服务器的路径 原先写法:connect.static(options.base[0])  
  15.         serveStatic(options.base[0]),  
  16.         // 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])  
  17.         serveIndex(options.base[0])  
  18.       ];  
  19.     };  
  20.   
  21.     grunt.initConfig({  
  22.         pkg: grunt.file.readJSON('package.json'),  
  23.         //这里要写之后的任务  
  24.           
  25.         //connect配置,自动加载web server服务器  
  26.         connect: {  
  27.                 options: {  
  28.                     protocol: 'http',  
  29.                     port: 8081,  
  30.                     hostname: '*',  
  31.                     open:true,  
  32.                     /*keepalive: true,*/  
  33.                     base: ['./']  
  34.                 },  
  35.                 livereload: {  
  36.                 options: {  
  37.                 // 通过LiveReload脚本,让页面重新加载。  
  38.                 middleware: lrMiddleware  
  39.                 }  
  40.             }  
  41.         },  
  42.     });  
  43.   
  44.     //引入插件  
  45.     grunt.loadNpmTasks('grunt-contrib-connect');  
  46.   
  47.   
  48.     //default任务,即默认任务,执行命令为grunt或grunt default  
  49.     grunt.registerTask('default',['connect']);  
  50.   
  51.     //两个任务名字不同可同时存在,执行时只要输入grunt+名字即可,如下:grunt start  
  52.     grunt.registerTask('start',['connect']);  
  53.   
  54.   
  55.     //这是之后配置的稍复杂的任务,这里我们先注释掉,稍后解释。  
  56.     //grunt.registerTask('import',['wiredep']);  
  57.     //grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);  
  58.     //grunt.registerTask('start',['connect','watch:start']);  
  59. };  
task配置完成,代码中也注释了语句分别是什么,然后我们执行一下任务

服务器配置成功,当然这时实时修改文件并不能直接让浏览器刷新,我们还需要一个监听插件,即grunt-contrib-watch

6.2grunt-contrib-watch

作用:实时监控文件变化、调用相应的任务重新执行,即配置文件的监听,在文件有变动时候执行task

安装方法:命令提示符输入 cnpm install grunt-contrib-watch --save-dev

安装具体过程同上就不具体说了,不同的地方就是需要配置新的任务,直接给出配置后的Gruntfile.js详情

[javascript]  view plain  copy
  1. module.exports = function(grunt){  
  2.   
  3.      // LiveReload的默认端口号,你也可以改成你想要的端口号  
  4.     var lrPort = 35729;  
  5.     var serveStatic = require('serve-static');  
  6.     var serveIndex = require('serve-index')  
  7.      // 使用connect-livereload模块,生成一个与LiveReload脚本  
  8.      // <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>  
  9.      var lrSnippet = require('connect-livereload')({ port: lrPort });  
  10.      // 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件  
  11.     var lrMiddleware = function(connect, options, middlwares) {  
  12.       return [  
  13.         lrSnippet,  
  14.         // 静态文件服务器的路径 原先写法:connect.static(options.base[0])  
  15.         serveStatic(options.base[0]),  
  16.         // 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])  
  17.         serveIndex(options.base[0])  
  18.       ];  
  19.     };  
  20.   
  21.     grunt.initConfig({  
  22.         pkg: grunt.file.readJSON('package.json'),  
  23.         //这里要写之后的任务  
  24.           
  25.         //connect配置,自动加载web server服务器  
  26.         connect: {  
  27.                 options: {  
  28.                     protocol: 'http',  
  29.                     port: 8081,  
  30.                     hostname: '*',  
  31.                     open:true,  
  32.                     /*keepalive: true,*/  
  33.                     base: ['./']  
  34.                 },  
  35.                 livereload: {  
  36.                 options: {  
  37.                 // 通过LiveReload脚本,让页面重新加载。  
  38.                 middleware: lrMiddleware  
  39.                 }  
  40.             }  
  41.         },  
  42.         //watch的配置(监听器)  
  43.         watch:{  
  44.                 start:{  
  45.                     files: ['*.html''css/*''js/*''images/**/*','dist/*','src/*','src/js/*'],  
  46.                     options: {  
  47.                         livereload: lrPort  
  48.                     }  
  49.                 }  
  50.             },  
  51.     });  
  52.   
  53.     //引入插件  
  54.     grunt.loadNpmTasks('grunt-contrib-connect');  
  55.     grunt.loadNpmTasks('grunt-contrib-watch');  
  56.   
  57.   
  58.     //default任务,即默认任务,执行命令为grunt或grunt default  
  59.     grunt.registerTask('default',['connect']);  
  60.   
  61.     //两个任务名字不同可同时存在,执行时只要输入grunt+名字即可,如下:grunt start  
  62.     grunt.registerTask('start',['connect','watch:start']);  
  63.   
  64.   
  65.     //这是之后配置的稍复杂的任务,这里我们先注释掉,稍后解释。  
  66.     //grunt.registerTask('import',['wiredep']);  
  67.     //grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);  
  68.     //grunt.registerTask('start',['connect','watch:start']);  
  69. };  

然后命令行执行task:grunt start

可以直接自动打开浏览器,并且进入到服务器的文件夹中,说明本地的文件夹已经放到服务器上,可以进行访问了

设置好对应文件的监听之后,我们可以看到当文件进行修改之后,会生成如下日志,并自动刷新页面

6.3常用插件配置介绍

本文中所有任务Gruntfile.js源码及讲解:

[javascript]  view plain  copy
  1. module.exports = function(grunt){  
  2.   
  3.  // LiveReload的默认端口号,你也可以改成你想要的端口号  
  4. var lrPort = 35729;  
  5. var serveStatic = require('serve-static');  
  6. var serveIndex = require('serve-index')  
  7.  // 使用connect-livereload模块,生成一个与LiveReload脚本  
  8.  // <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>  
  9.  var lrSnippet = require('connect-livereload')({ port: lrPort });  
  10.  // 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件  
  11. var lrMiddleware = function(connect, options, middlwares) {  
  12.   return [  
  13.     lrSnippet,  
  14.     // 静态文件服务器的路径 原先写法:connect.static(options.base[0])  
  15.     serveStatic(options.base[0]),  
  16.     // 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])  
  17.     serveIndex(options.base[0])  
  18.   ];  
  19. };  
  20.   
  21.         grunt.initConfig({  
  22.             pkg: grunt.file.readJSON('package.json'),  
  23.             //uglify的配置(js压缩)  
  24.             uglify: {  
  25.                 options: {  
  26.                     // 此处定义的banner注释将插入到输出文件的顶部  
  27.                     mangle: false//不混淆变量名  
  28.                     preserveComments: 'some'//不删除注释,还可以为 false(删除全部注释),some(保留@preserve @license @cc_on等注释  
  29.                     banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'  
  30.                 },  
  31.                 dist: {  
  32.                     options: {  
  33.                         report: "min",//输出压缩率,可选的值有 false(不输出信息),gzip  
  34.                     },  
  35.                     files: {  
  36.                         //uglify会自动压缩concat任务中生成的文件  
  37.                         'dist/js/app.min.js': ['dist/js/app.js']  
  38.                     }  
  39.                 }  
  40.             },  
  41.             //jshint的配置(代码校验)  
  42.             jshint:{  
  43.                 build:['src/js/test.js'],  
  44.                 options:{  
  45.                     //这里是覆盖JSHint默认配置的选项  
  46.                     globals: {  
  47.                     jQuery: true,  
  48.                     console: true,  
  49.                     module: true,  
  50.                     document: true  
  51.                     }  
  52.                 }  
  53.             },  
  54.             //watch的配置(监听器)  
  55.             watch:{  
  56.                 build:{  
  57.                     files:['src/*.js'],  
  58.                     tasks:['jshint','uglify'],  
  59.                     options:{spawn:false}  
  60.                 },  
  61.                 start:{  
  62.                     files: ['*.html''css/*''js/*''images/**/*','dist/*','src/*','src/js/*'],  
  63.                     options: {  
  64.                         livereload: lrPort  
  65.                     }  
  66.                 }  
  67.             },  
  68.             //wiredep的配置(自动将bower下载的包导入html中)  
  69.             wiredep: {  
  70.                 target: {  
  71.                     src: ['src/*.html'],  
  72.                     directory:"js/libs"  
  73.                 }  
  74.             },  
  75.             //connect配置,自动加载web server服务器  
  76.             connect: {  
  77.                     options: {  
  78.                         protocol: 'http',  
  79.                         port: 8081,  
  80.                         hostname: '*',  
  81.                         open:true,  
  82.                         /*keepalive: true,*/  
  83.                         base: ['./']  
  84.                     },  
  85.                     livereload: {  
  86.                     options: {  
  87.                     // 通过LiveReload脚本,让页面重新加载。  
  88.                     middleware: lrMiddleware  
  89.                     }  
  90.                 }  
  91.             },  
  92.   
  93.   
  94.             useminPrepare: {  
  95.                 html: 'src/*.html',  
  96.                     options: {  
  97.                     dest: 'dist'  
  98.                 }  
  99.             },  
  100.             usemin: {  
  101.                 html: ['dist/*.html']  
  102.             },  
  103.             //copy任务,将src下的copy到dist  
  104.             copy:{  
  105.                 js:{  
  106.                     expand:true,  
  107.                     cwd:'src/',  
  108.                     src:['*.html'],  
  109.                     dest:'dist/',  
  110.                 },  
  111.             },  
  112.             //合并  
  113.             concat:{  
  114.                 options: {  
  115.                   separator: ';',  
  116.                   stripBanners: true,  
  117.                   banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'  
  118.                 },  
  119.                 dist: {  
  120.                   src: ['src/js/*.js'],  
  121.                   dest: 'dist/js/app.js',  
  122.                 }  
  123.             },  
  124.         });  
  125.   
  126.   
  127.   
  128.   
  129.         grunt.loadNpmTasks('grunt-contrib-uglify');  
  130.         grunt.loadNpmTasks('grunt-contrib-jshint');  
  131.         grunt.loadNpmTasks('grunt-contrib-watch');  
  132.         grunt.loadNpmTasks('grunt-wiredep');  
  133.         grunt.loadNpmTasks('grunt-contrib-connect');  
  134.         grunt.loadNpmTasks('grunt-usemin');  
  135.         grunt.loadNpmTasks('grunt-contrib-copy');  
  136.         grunt.loadNpmTasks('grunt-contrib-concat');  
  137.   
  138.         grunt.registerTask('import',['wiredep']);  
  139.   
  140.         grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);  
  141.   
  142.         grunt.registerTask('start',['connect','watch:start']);  
  143. }  

以上的三个任务:grunt import、grunt package、grunt start都是我自行进行任务组合配置的,当然如果你足够熟悉每一种插件的作用,完全可以自己进行相应任务的调配。

这些插件的首次安装方式都为:cnpm install 插件名 --save-dev ,这里就不去一一描述了,下载自己需要的插件就可以了

7.发布正式版及插件批量安装

    我们在发布正式版本的时候,是不需要node_modules这个文件夹的,但在开发的时候是需要的,所以我们在发布正式版本的时候,是需要将我们的源代码修改为发布版本之后,保留我们的Gruntfile.js以及package.jsonjson,在命令提示符中输入npm install 即可生成一个node_modules文件夹并安装在package.json的devDependencies中所有的插件,有可能由于网络波动导致安装失败,多装几次就行了。

    如果你想测试一下如上所说的话,将目录中的node_modules删掉,输入npm install即可。

8.集成bower

    我们已经知道了前端开发时,可以进行使用一些插件以协助我们开发,当然当项目上线的时候,是不需要这些插件的。而我们项目中所用到的一些插件,如bootstrap,jquery这些常用的插件,我们需要去官网找并下载源码,那么有没有一种方式来简化这个过程呢,当然,这就是bower

8.1 bower安装

bower大概的意义就是项目中的包管理

安装方法:npm install -g bower

其中-g的意思是全局安装

当我们使用bower进行包的安装时,其路径并不是我们的安装路径

所以我们引入一个.bowerrc文件,注意是以“.”开头的,其内容为:

{
    "directory": "js/libs"
}

这样,我们通过bower安装的文件路径就都为:js下的lib中了

8.2 初始化

bower安装完成后需要进行初始化:

即在命令提示符中输入 bower init,同npm init相同的,也需要输入一些信息,当然也可以一路回车,然后最后确定即可。可以发现目录中的多了bower.json文件

[javascript]  view plain  copy
  1. {  
  2.   "name""new_test_project",  
  3.   "description""test",  
  4.   "main""index.js",  
  5.   "authors": [  
  6.     "ds"  
  7.   ],  
  8.   "license""ISC",  
  9.   "homepage""",  
  10.   "ignore": [  
  11.     "**/.*",  
  12.     "node_modules",  
  13.     "bower_components",  
  14.     "test",  
  15.     "tests"  
  16.   ]  
  17. }  

8.3 包的安装

这里我们用jquery举例

安装方法:命令提示符bower install --save jquery


然后bower就会从远程下载jquery最新版本到你的js/lib目录下
其中--save参数是保存配置到你的bower.json,你会发现bower.json文件已经多了一行:


我们到文件夹中去看,项目根目录下的js/libs多了jquery的源文件

8.4 包的信息

命令提示符输入:bower info jquery



即可看到jquerybower.json的信息,和可用的版本信息

8.5包的更新

想要修改jquery的版本,只要修改bower.json中为:

[javascript]  view plain  copy
  1. "dependencies": {  
  2.     "jquery""~1.11.3"  
  3.   }  

然后执行  bower update 就可以就行版本的切换了

8.5 包的查找

命令提示符输入bower search +关键字, 如bower search bootstr,即可搜索出包含bootstr字段的所有可用的包


8.6包的卸载

包的卸载为unstall命令

如jquery的卸载:bower uninstall jquery



开发过程中使用命令:

grunt serve:开发环境,试试编译本地代码,及时查看效果;

grunt test:测试环境,基于本地生成测试模拟;

grunt dist:发布打包,于dist文件夹中生成可部署文件包;


猜你喜欢

转载自blog.csdn.net/zyx1303031629/article/details/80495784
今日推荐