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文件,内容为:
- {
- "name": "new_test_project",
- "version": "1.0.0",
- "description": "test",
- "main": "index.js",
- "directories": {
- "test": "test"
- },
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "author": "ds",
- "license": "ISC"
- }
其中左边的名称是不可以更改的,右边的一些相当于参数的东西是可以进行更改的。
2.(推荐)在当前也就是D:\1Project Workspace\New_Test_Project这个目录下shift+右键打开命令行,输入npm init,回车键然后按照所需信息一步一步填写下来,项目名必须都是小写字母,版本号、简介等都可以不填写,一路回车下来,最后输入yes,就会发现这个文件已经建立好了:
4.安装grunt
接下来就是正主grunt的安装了,这里首先介绍一下更改npm下载源的方法,网足够好的可以跳过4.1的步骤接着往下看
4.1将下载源从国外改到淘宝
由于国外网络受网络波动影响大,时常导致下载失败,所以我们的淘宝团队将这些国外的镜像到了国内。
官方:这是一个完整 npmjs.org
镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。
执行:
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文件中的信息
- module.exports = function(grunt){
- grunt.initConfig({
- pkg: grunt.file.readJSON('package.json'),
- //这里要写之后的任务
- });
- //default任务,即默认任务,执行命令为grunt或grunt default
- grunt.registerTask('default',[]);
- //这是之后配置的稍复杂的任务,这里我们先注释掉,稍后解释。
- //grunt.registerTask('import',['wiredep']);
- //grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
- //grunt.registerTask('start',['connect','watch:start']);
- };
同时我们再回去看一眼源代码,其它注释掉但有内容的执行方式分别是: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修改一些配置
- module.exports = function(grunt){
- // LiveReload的默认端口号,你也可以改成你想要的端口号
- var lrPort = 35729;
- var serveStatic = require('serve-static');
- var serveIndex = require('serve-index')
- // 使用connect-livereload模块,生成一个与LiveReload脚本
- // <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>
- var lrSnippet = require('connect-livereload')({ port: lrPort });
- // 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件
- var lrMiddleware = function(connect, options, middlwares) {
- return [
- lrSnippet,
- // 静态文件服务器的路径 原先写法:connect.static(options.base[0])
- serveStatic(options.base[0]),
- // 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])
- serveIndex(options.base[0])
- ];
- };
- grunt.initConfig({
- pkg: grunt.file.readJSON('package.json'),
- //这里要写之后的任务
- //connect配置,自动加载web server服务器
- connect: {
- options: {
- protocol: 'http',
- port: 8081,
- hostname: '*',
- open:true,
- /*keepalive: true,*/
- base: ['./']
- },
- livereload: {
- options: {
- // 通过LiveReload脚本,让页面重新加载。
- middleware: lrMiddleware
- }
- }
- },
- });
- //引入插件
- grunt.loadNpmTasks('grunt-contrib-connect');
- //default任务,即默认任务,执行命令为grunt或grunt default
- grunt.registerTask('default',['connect']);
- //两个任务名字不同可同时存在,执行时只要输入grunt+名字即可,如下:grunt start
- grunt.registerTask('start',['connect']);
- //这是之后配置的稍复杂的任务,这里我们先注释掉,稍后解释。
- //grunt.registerTask('import',['wiredep']);
- //grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
- //grunt.registerTask('start',['connect','watch:start']);
- };
服务器配置成功,当然这时实时修改文件并不能直接让浏览器刷新,我们还需要一个监听插件,即grunt-contrib-watch
6.2grunt-contrib-watch
作用:实时监控文件变化、调用相应的任务重新执行,即配置文件的监听,在文件有变动时候执行task
安装方法:命令提示符输入 cnpm install grunt-contrib-watch --save-dev
安装具体过程同上就不具体说了,不同的地方就是需要配置新的任务,直接给出配置后的Gruntfile.js详情
- module.exports = function(grunt){
- // LiveReload的默认端口号,你也可以改成你想要的端口号
- var lrPort = 35729;
- var serveStatic = require('serve-static');
- var serveIndex = require('serve-index')
- // 使用connect-livereload模块,生成一个与LiveReload脚本
- // <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>
- var lrSnippet = require('connect-livereload')({ port: lrPort });
- // 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件
- var lrMiddleware = function(connect, options, middlwares) {
- return [
- lrSnippet,
- // 静态文件服务器的路径 原先写法:connect.static(options.base[0])
- serveStatic(options.base[0]),
- // 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])
- serveIndex(options.base[0])
- ];
- };
- grunt.initConfig({
- pkg: grunt.file.readJSON('package.json'),
- //这里要写之后的任务
- //connect配置,自动加载web server服务器
- connect: {
- options: {
- protocol: 'http',
- port: 8081,
- hostname: '*',
- open:true,
- /*keepalive: true,*/
- base: ['./']
- },
- livereload: {
- options: {
- // 通过LiveReload脚本,让页面重新加载。
- middleware: lrMiddleware
- }
- }
- },
- //watch的配置(监听器)
- watch:{
- start:{
- files: ['*.html', 'css/*', 'js/*', 'images/**/*','dist/*','src/*','src/js/*'],
- options: {
- livereload: lrPort
- }
- }
- },
- });
- //引入插件
- grunt.loadNpmTasks('grunt-contrib-connect');
- grunt.loadNpmTasks('grunt-contrib-watch');
- //default任务,即默认任务,执行命令为grunt或grunt default
- grunt.registerTask('default',['connect']);
- //两个任务名字不同可同时存在,执行时只要输入grunt+名字即可,如下:grunt start
- grunt.registerTask('start',['connect','watch:start']);
- //这是之后配置的稍复杂的任务,这里我们先注释掉,稍后解释。
- //grunt.registerTask('import',['wiredep']);
- //grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
- //grunt.registerTask('start',['connect','watch:start']);
- };
然后命令行执行task:grunt start
可以直接自动打开浏览器,并且进入到服务器的文件夹中,说明本地的文件夹已经放到服务器上,可以进行访问了
设置好对应文件的监听之后,我们可以看到当文件进行修改之后,会生成如下日志,并自动刷新页面
6.3常用插件配置介绍
本文中所有任务Gruntfile.js源码及讲解:
- module.exports = function(grunt){
- // LiveReload的默认端口号,你也可以改成你想要的端口号
- var lrPort = 35729;
- var serveStatic = require('serve-static');
- var serveIndex = require('serve-index')
- // 使用connect-livereload模块,生成一个与LiveReload脚本
- // <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>
- var lrSnippet = require('connect-livereload')({ port: lrPort });
- // 使用 middleware(中间件),就必须关闭 LiveReload 的浏览器插件
- var lrMiddleware = function(connect, options, middlwares) {
- return [
- lrSnippet,
- // 静态文件服务器的路径 原先写法:connect.static(options.base[0])
- serveStatic(options.base[0]),
- // 启用目录浏览(相当于IIS中的目录浏览) 原先写法:connect.directory(options.base[0])
- serveIndex(options.base[0])
- ];
- };
- grunt.initConfig({
- pkg: grunt.file.readJSON('package.json'),
- //uglify的配置(js压缩)
- uglify: {
- options: {
- // 此处定义的banner注释将插入到输出文件的顶部
- mangle: false, //不混淆变量名
- preserveComments: 'some', //不删除注释,还可以为 false(删除全部注释),some(保留@preserve @license @cc_on等注释
- banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
- },
- dist: {
- options: {
- report: "min",//输出压缩率,可选的值有 false(不输出信息),gzip
- },
- files: {
- //uglify会自动压缩concat任务中生成的文件
- 'dist/js/app.min.js': ['dist/js/app.js']
- }
- }
- },
- //jshint的配置(代码校验)
- jshint:{
- build:['src/js/test.js'],
- options:{
- //这里是覆盖JSHint默认配置的选项
- globals: {
- jQuery: true,
- console: true,
- module: true,
- document: true
- }
- }
- },
- //watch的配置(监听器)
- watch:{
- build:{
- files:['src/*.js'],
- tasks:['jshint','uglify'],
- options:{spawn:false}
- },
- start:{
- files: ['*.html', 'css/*', 'js/*', 'images/**/*','dist/*','src/*','src/js/*'],
- options: {
- livereload: lrPort
- }
- }
- },
- //wiredep的配置(自动将bower下载的包导入html中)
- wiredep: {
- target: {
- src: ['src/*.html'],
- directory:"js/libs"
- }
- },
- //connect配置,自动加载web server服务器
- connect: {
- options: {
- protocol: 'http',
- port: 8081,
- hostname: '*',
- open:true,
- /*keepalive: true,*/
- base: ['./']
- },
- livereload: {
- options: {
- // 通过LiveReload脚本,让页面重新加载。
- middleware: lrMiddleware
- }
- }
- },
- useminPrepare: {
- html: 'src/*.html',
- options: {
- dest: 'dist'
- }
- },
- usemin: {
- html: ['dist/*.html']
- },
- //copy任务,将src下的copy到dist
- copy:{
- js:{
- expand:true,
- cwd:'src/',
- src:['*.html'],
- dest:'dist/',
- },
- },
- //合并
- concat:{
- options: {
- separator: ';',
- stripBanners: true,
- banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
- },
- dist: {
- src: ['src/js/*.js'],
- dest: 'dist/js/app.js',
- }
- },
- });
- grunt.loadNpmTasks('grunt-contrib-uglify');
- grunt.loadNpmTasks('grunt-contrib-jshint');
- grunt.loadNpmTasks('grunt-contrib-watch');
- grunt.loadNpmTasks('grunt-wiredep');
- grunt.loadNpmTasks('grunt-contrib-connect');
- grunt.loadNpmTasks('grunt-usemin');
- grunt.loadNpmTasks('grunt-contrib-copy');
- grunt.loadNpmTasks('grunt-contrib-concat');
- grunt.registerTask('import',['wiredep']);
- grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
- grunt.registerTask('start',['connect','watch:start']);
- }
以上的三个任务: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文件
- {
- "name": "new_test_project",
- "description": "test",
- "main": "index.js",
- "authors": [
- "ds"
- ],
- "license": "ISC",
- "homepage": "",
- "ignore": [
- "**/.*",
- "node_modules",
- "bower_components",
- "test",
- "tests"
- ]
- }
8.3 包的安装
这里我们用jquery举例
安装方法:命令提示符bower install --save jquery
然后bower
就会从远程下载jquery
最新版本到你的js/lib
目录下
其中--save
参数是保存配置到你的bower.json
,你会发现bower.json
文件已经多了一行:
我们到文件夹中去看,项目根目录下的js/libs多了jquery的源文件
8.4 包的信息
命令提示符输入:bower info jquery
即可看到jquery
的bower.json
的信息,和可用的版本信息
8.5包的更新
想要修改jquery的版本,只要修改bower.json中为:
- "dependencies": {
- "jquery": "~1.11.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文件夹中生成可部署文件包;