在不久前我曾写了一篇 应用r.js来优化你的前端 的文章,为大家介绍了r.js这个实用工具,它可以很好地压缩、合并前端文件并打包整个项目。但是如果将r.js放到项目中,我们不得不顾及到一个问题——项目每维护一次,就需要维护的人员输入一次rjs运行口令重新打包项目,自然是非常繁琐的事情。另外如果我们的项目用sass来写样式,可能还得外开一个koala。如果我们能让项目自己处理自己的所有事宜,那一切就美好多了。

针对上述问题,今天我们就利用更为大众的工具——Grunt,来自动化地处理前端事务(其实rjs也是使用了Grunt的concat和uglify等插件)。

我们依旧使用一个非常简单的、名为before的项目(你可以在我的Github下载这个案例)来作为示例,它是一个很纯净的项目,还没有使用任何前端工具对其进行操作:

你可以试着运行根目录下的index.html文件,它会显示一张幻灯片。

接下来我们将在before项目上使用Grunt自动化前端事务。

操作需求

由于Grunt是运行与node上的,故要求你的电脑安装了nodeJS(点我下载);

由于我们这边使用了sass来写样式,故要求你的电脑安装了Ruby(注意Mac是默认安装有Ruby的,如果是Windows或其它系统请点此下载安装)。

安装时建议把三个可以勾选的选项都勾上(特别要勾选上第二个,这样才会添加环境变量),安装后点击 “所有程序” -  “Ruby.13...” -  “start command prompt with Ruby”,打开Ruby命令行界面并输入指令:

gem install sass

注意该指令必须要在翻墙的情况下才执行,不然可能会导致无法安装sass的错误:

不过有时候系统可能会提示这个错误信息:

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://bb-m.rubygems.org/gems/multi_json-1.3.2.gem)

解决方法是在这里下载证书(http://curl.haxx.se/ca/cacert.pem),比如下载到 D:/ruby/cacert.pem, 然后再环境变量里新建一个SSL_CERT_FILE这个环境变量,并把变量值设为这个文件路径即可:

另外,我们后续编译sass的时候,若.scss文件中存在中文注释,Ruby可能会因为识别不了中文编码而导致出错。不过解决方法很简单,点击此处查看

安装GRUNT CLI

我们打开 Node.js command prompt 进入node命令行界面:

在命令行界面输入以下代码并回车运行,此举是安装Grunt全局命令行,从而我们可以在电脑任何位置调用grunt命令语句:

npm install -g grunt-cli

Grunt配置

Grunt的入门其实可以参考官方入门,虽然这篇官方指引写的很烂,却也告诉我们,Grunt配置离不开两个文件—— package.jsonGruntfile.js ,我们一般都把它们放置在项目根目录上 。

其中 package.json 作用是记录项目的名称(随便起个名字就行)、版本号(随便起个数字串就行)和插件依赖,创建package.json完全不用手动,我们只需要把node命令行定位到项目下(假设我们把上述的before项目放在E盘),然后输入以下指令并回车执行,便会在项目根目录自动创建一个初始化的 package.json 文件:

npm init

回车后node会问你若干个问题,包括项目名啊版本号啊什么有的没的,你有心情可以写一写,没心情就一路按回车下来即可:

这时你会发现根目录下就这样多了个叫package.json的文件:

里面有node帮我们预先定义好的json代码。不过我各人并不喜欢使用 npm init 这种婆妈的形式来自动生成package.json,还不如自己手动创建一个package.json,并输入简洁的代码:

{
"name": "before",
"version": "1.0.0"
}

是的,初始化咱只要就这么俩行即可,其实我甚至希望能简短到只有 {  } 即可。可惜 name 和 version 对于 package.json 来说是非常重要的俩个属性,缺一不可(可以查看这里了解更多package.json属性的作用)

安装插件

Grunt只是一个载体,实际要用起来得使用各种五花八门的grunt插件(有点类似在Sublime上我们可以安装并使用各种sb插件)。

而我们的before项目需要运用到下面几个插件:

grunt —— 这个不用说了,就是Grunt它自己本身;

grunt-contrib-uglify —— 作用是压缩项目js文件;

grunt-contrib-sass —— 作用是编译项目中的sass为(压缩版的)css文件;

grunt-contrib-watch —— 作用是实现我们一开始需求的“自动化”!是最重要的一个插件之一!它会监听需要处理的文件的变动,一旦有变动就会自动执行相应处理。但是它有一个问题,就是每当监听到一处变动时,就会大费周章地把所有被监听的文件都处理一遍;

grunt-newer —— 作用是处理上方watch的毛病,让watch在监听到某个文件变动时,仅仅对变动的文件进行事务处理。

然而在node中,安装grunt插件的命令为:

npm install <插件名> --save-dev

其中后面的 “--save-dev” 表示保存为依赖,即在安装好插件后,会将此插件依赖写入package.json文件中(记得我们前面说到package.json的作用之一是记录项目的插件依赖么)。

于是我们在项目的根目录下分别运行下述命令安装插件:

npm install grunt --save-dev

npm install grunt-contrib-uglify --save-dev

npm install grunt-contrib-sass --save-dev

npm install grunt-contrib-watch --save-dev

运行时可能会提示如下的警告:

这是因为咱在package.json里没有写一些description等婆妈的东西,故这里的WARN不痛不痒直接无视它即可。

插件安装好后会发现项目根目录上多了个叫“node_modules”的文件夹,是用来存放我们安装好的插件的。另外我们打开package.json,会发现它已经自动加入了插件依赖信息:

配置Gruntfile.js文件

开始我们就提到grunt有2个不可缺少的文件 —— package.json 和 Gruntfile.js 文件,package.json咱已轻松搞定,下面新建一个Gruntfile.js 文件并输入以下代码:

module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//上面是固定好的,不用管它,照搬即可。
//下面是各插件事务的配置,顺序不分先后
sass: { // grunt-contrib-sass的事务定义
tocss: {
options: {
style: 'compressed', //以压缩模式编译css,这样咱们也没必要使用grunt-contrib-cssmin插件了
sourcemap:'none' //设置不要配套输出map文件
},
files: [{
expand:true,
cwd:'css',//css目录下
src:'**/*.scss',//所有css文件
dest: 'css',//输出到此目录下
ext: '.css'
}]
}
},
uglify: { // grunt-contrib-uglify的事务定义
compressjs: {
files: [{
expand:true,
cwd:'js',//js目录下
src:'**/*.js',//所有js文件
dest: 'output/js'//输出到此目录下
}]
}
},
watch: { // grunt-contrib-watch的事务定义
all: {
files: ['css/**/*.scss','js/**/*.js'],
tasks: ['newer:sass','newer:uglify']
}
}
});
//grunt.loadNpmTasks() 是告诉Grunt,咱们要使用哪些插件,顺序不分先后
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-newer');
//grunt.registerTask('default', [])是告诉Grunt,我们在node命令行输入grunt指令后要执行哪些事务
grunt.registerTask('default', ['newer:sass','newer:uglify','watch']); //注意 "newer:XXX"是插件grunt-newer的事件定义,表示对冒号后面的事务生效
};

Gruntfile.js的配置或许算是配置Grunt的一个难点吧,它的作用是告诉Grunt要使用哪些插件(安装了不代表一定要用对吧,当然要用的话一定得安装)、每个插件又要进行怎样的事务操作。

其实Gruntfile.js最最简单的初始化框架是这样的:

module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'), 插件事务名称: {
........//事务定义
}
});
//grunt.loadNpmTasks() 是告诉Grunt,咱们要使用哪些插件,顺序不分先后
grunt.loadNpmTasks('插件名'); //grunt.registerTask('default', [])是告诉Grunt,我们在node命令行输入grunt指令后要执行哪些事务
grunt.registerTask('default', ['插件事务名称']);
};

稍微推敲下,很容易理解代码的含义。如若了解更灵活、复杂的Gruntfile.js配置,可以点此查看指引

一切都捣鼓好后,我们可以直接在node命令行(依旧定位在根目录下哦,其实可以不用再唠嗑了)输入

grunt

回车执行后便进入自动化执行状态,只要有js或者scss文件变动,变动的文件就会重新被压缩或编译:

像本章的例子是使用了sass来写样式,如果你只写原生的css,又希望能压缩样式文件,那么可以使用 grunt-contrib-cssmin 插件,其具体配置可以点此查看,本文就不赘述了。

共勉~

应用Grunt自动化地优化你的项目前端的更多相关文章

  1. Grunt自动化构建工具(网址:http://www.gruntjs.net/getting-started或者http://gruntjs.cn/getting-started)

    简介:Grunt是基于Node.js的项目构建工具,对于需要重复执行的任务,例如压缩.编译.单元测试等,自动化工具可以减少你的工作量,使你的工作更轻松. 一:检测nodejs是否安装好,打开CMD控制 ...

  2. Grunt自动化工具相关

    Grunt 项目中安装grunt模块npm install grunt --save,删除模块 npm uninstall grunt ,缺失某个插件:npm install grunt-contri ...

  3. JavaScript 项目构建工具 Grunt 实践:安装和创建项目框架

     Grunt 是一个基于任务的 JavaScript 项目命令行构建工具,运行于 Node.js 平台.Grunt 能够从模板快速创建项目,合并.压缩和校验 CSS & JS 文件,运行单元测 ...

  4. NPM、nodeJS安装,grunt自动化构建工具学习总结

    一:安装 npm是随nodeJs安装包一起安装的包管理工具,能解决NodeJS代码部署上的很多问题: 常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从N ...

  5. 优化vue+springboot项目页面响应时间:waiting(TTFB) 及content Download

    优化vue+springboot项目页面响应时间:waiting(TTFB) 及content Download TTFB全称Time To First Byte,是指网络请求被发起到从服务器接收到地 ...

  6. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  7. 【前端福利】用grunt搭建自己主动化的web前端开发环境-完整教程

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发者.假设你如今还不知道grunt或者听说过. ...

  8. 使用gulp解决RequireJS项目前端缓存问题(二)

    1.前言 这一节,我们主要解决在上一节<使用gulp解决RequireJSs项目前端缓存问题(一)>末尾提到的几个问题: 对通过require-config.js引入的js文件修改后,没有 ...

  9. 使用gulp解决RequireJS项目前端缓存问题(一)

    1.前言 前端缓存一直是个令人头疼的问题,你有可能见过下面博客园首页的资源文件链接: 有没有发现文件名后面有一串不规则的东东,没错,这就是运用缓存机制,我们今天研究的就是这种东西. 先堵为快,猛戳链接 ...

随机推荐

  1. js实现前端分页页码管理

    用JS实现前端分页页码管理,可以很美观的区分页码显示(这也是参考大多数网站的分页页码展示),能够有很好的用户体验,这也是有业务需要就写了一下,还是新手,经验不足,欢迎指出批评! 首先先看效果图: 这是 ...

  2. Electron使用与学习--(基本使用与菜单操作)

    对于electron是个新手,下面纯属个人理解.如有错误,欢迎指出.   一.安装 如果你本地按照github上的 # Install the `electron` command globally ...

  3. 神经网络、logistic回归等分类算法简单实现

    最近在github上看到一个很有趣的项目,通过文本训练可以让计算机写出特定风格的文章,有人就专门写了一个小项目生成汪峰风格的歌词.看完后有一些自己的小想法,也想做一个玩儿一玩儿.用到的原理是深度学习里 ...

  4. C#异步编程(二)

    async和await结构 序 前篇博客异步编程系列(一) 已经介绍了何谓异步编程,这篇主要介绍怎么实现异步编程,主要通过C#5.0引入的async/await来实现. BeginInvoke和End ...

  5. 快递Api接口 & 微信公众号开发流程

    之前的文章,已经分析过快递Api接口可能被使用的需求及场景:今天呢,简单给大家介绍一下微信公众号中怎么来使用快递Api接口,来完成我们的需求和业务场景. 开发语言:Nodejs,其中用到了Neo4j图 ...

  6. PHP好用但又容易忽略的小知识

    1.PHP函数之判断函数是否存在 当我们创建了自定义函数,并且了解了可变函数的用法,为了确保程序调用的函数是存在的,经常会先使用function_exists判断一下函数是否存在.同样的method_ ...

  7. 在DevExpress程序中使用GridView直接录入数据的时候,增加列表选择的功能

    在我上篇随笔<在DevExpress程序中使用Winform分页控件直接录入数据并保存>中介绍了在GridView以及在其封装的分页控件上做数据的直接录入的处理,介绍情况下数据的保存和校验 ...

  8. C#发送邮箱

    之前自己从来没有做过发送邮箱的功能,前段时间项目需要,在找了很多帖子之后,终于实现了. 之后有整理了一下,写了一个类.直接给类传递信息,就可以发送了. 这里还需要说明的是,发送邮箱需要开通POP3/S ...

  9. SSH框架和Redis的整合(2)

    5. 添加功能的实现 新建一个Action:RClasAction,实现向Redis添加课程数据,并同步到MySQL. package com.school.action; import java.u ...

  10. SQL-类型转换函数

    CAST ( expression AS data_type)CONVERT ( data_type, expression,[style]) Select '您的班级编号'+ 1  错误这里+是数学 ...