首先要感谢那些知名的不知名的前辈们,你们的成就是我们进步的基础。
本文针对的读者是那些像之前的我一样刚刚了解Grunt和Bower这两个名字是什么,但还不知道究竟是干什么的,同样是以应用为主,已经会基本使用这些的就不需要看了,因为都是最基础的一些东西,同样如果您看了之后发现有什么不符合逻辑或常识的问题,或是有什么错误,我会非常期待您的指正。
grunt以及其插件都是需要依赖nodejs来运行的,所以如果你的电脑中并没有安装,那么需要安装nodejs,安装过程极其简单,就是傻瓜式的下一步直到install即可
nodejs官网:https://nodejs.org/en/
这是官网打开以后的图,我们这里安装左边的就可以了。
安装完成以后,win+r cmd 打开命令提示符窗口,输入node -v查看版本号,以验证nodejs是否安装成功
这里就与传统的安装软件方式不同了,以后安装的一些插件基本都是使用这样的方式安装的,所以先不用问这是什么东西,用的时间长了就明白是个什么东西了
首先使用nodejs的npm install方式安装grunt-CLI ,很简单,就是在命令行里输入npm install -g grunt-cli 然后回车键
分析一下这句安装命令分别代表什么:
npm install :nodejs的安装插件方式
-g:全局安装
grunt-cli:插件名
确保电脑联网且网足够快
如果安装成功的话会出现grunt-cli的目录结构,安装失败找出原因重新安装即可,成功后类似这样:
进行验证看是否安装成功:
命令行输入grunt 回车键,证明grunt-cli安装成功
grunt-cli到这里基本上就安装完成了,接下来建立一个自己的前端项目吧。
这里可以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,就会发现这个文件已经建立好了:
接下来就是正主grunt的安装了,这里首先介绍一下更改npm下载源的方法,网足够好的可以跳过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.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文件中写一些任务
打开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']);
};
这里我们配置好了一个叫default(默认)的任务,它的任务列表,也就是右边的数组是空的,所以它可以启动但是不执行什么任务,这里我们执行这个任务的方式就是在命令提示符中输入
grunt或
grunt default,可以得到如下结果
同时我们再回去看一眼源代码,其它注释掉但有内容的执行方式分别是:grunt import ; grunt package ; grunt start。而其后边的数组中就是它依次要去执行的任务,那这些任务是如何配置的呢,接下来就一一介绍
这里要用到的就是grunt的插件了,这些插件都是从官网被审核后才能上架下载的,当然我们不需要去官网再艾格寻找下载,用我们的npm方式安装即可,但有兴趣的依然可以去官网看一眼
官方地址:http://www.gruntjs.net/plugins
插件分为两类。第一类是grunt团队贡献的插件,这些插件的名字前面都带有“contrib-”前缀,而且在插件列表中有星号标注。第二类是第三方提供的插件,不带有这两个特征。
并不是所有的插件都需要被用到,这里我们只去介绍一些我们用到的,常用的,并且每个插件配置的不同,其用法也不尽相同:
接下来会大致讲解以下这些插件的用法,但不会详细介绍,只是应用,官网中还有许多更加优秀实用的插件,可以自行查找使用
先从应用的角度来看,我们先讲connect插件和watch插件,有了这两个之后,我们的前端开发就可以这边保存,浏览器中自动刷新看效果了
这个插件的作用是配置一个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脚本
//
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']);
};
task配置完成,代码中也注释了语句分别是什么,然后我们执行一下任务
服务器配置成功,当然这时实时修改文件并不能直接让浏览器刷新,我们还需要一个监听插件,即grunt-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脚本
//
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']);
};
可以直接自动打开浏览器,并且进入到服务器的文件夹中,说明本地的文件夹已经放到服务器上,可以进行访问了
设置好对应文件的监听之后,我们可以看到当文件进行修改之后,会生成如下日志,并自动刷新页面
本文中所有任务Gruntfile.js源码及讲解:
module.exports = function(grunt){
// LiveReload的默认端口号,你也可以改成你想要的端口号
var lrPort = 35729;
var serveStatic = require('serve-static');
var serveIndex = require('serve-index')
// 使用connect-livereload模块,生成一个与LiveReload脚本
//
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']);
}
这些插件的首次安装方式都为:cnpm install 插件名 --save-dev ,这里就不去一一描述了,下载自己需要的插件就可以了
我们在发布正式版本的时候,是不需要node_modules这个文件夹的,但在开发的时候是需要的,所以我们在发布正式版本的时候,是需要将我们的源代码修改为发布版本之后,保留我们的Gruntfile.js以及package.jsonjson,在命令提示符中输入npm install 即可生成一个node_modules文件夹并安装在package.json的devDependencies中所有的插件,有可能由于网络波动导致安装失败,多装几次就行了。
如果你想测试一下如上所说的话,将目录中的node_modules删掉,输入npm install即可。
我们已经知道了前端开发时,可以进行使用一些插件以协助我们开发,当然当项目上线的时候,是不需要这些插件的。而我们项目中所用到的一些插件,如bootstrap,jquery这些常用的插件,我们需要去官网找并下载源码,那么有没有一种方式来简化这个过程呢,当然,这就是bower
bower大概的意义就是项目中的包管理
安装方法:npm install -g bower
其中-g的意思是全局安装
当我们使用bower进行包的安装时,其路径并不是我们的安装路径
所以我们引入一个.bowerrc文件,注意是以“.”开头的,其内容为:
{
"directory": "js/libs"
}
这样,我们通过bower安装的文件路径就都为:js下的lib中了
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"
]
}
这里我们用jquery举例
安装方法:命令提示符bower install --save jquery
然后bower
就会从远程下载jquery
最新版本到你的js/lib
目录下
其中--save
参数是保存配置到你的bower.json
,你会发现bower.json
文件已经多了一行:
我们到文件夹中去看,项目根目录下的js/libs多了jquery的源文件
命令提示符输入:bower info jquery
即可看到jquery
的bower.json
的信息,和可用的版本信息
想要修改jquery的版本,只要修改bower.json中为:
"dependencies": {
"jquery": "~1.11.3"
}
命令提示符输入bower search +关键字, 如bower search bootstr,即可搜索出包含bootstr字段的所有可用的包
包的卸载为unstall命令
如jquery的卸载:bower uninstall jquery