原文:Grunt workflow for compiling Sass & Compass and minifying Javascript
以前,我们安装Node,NPM和Grunt还包括建立的一个package.json文件和一个Gruntfile文件。在这篇让人兴奋的文章中,我们将会填补一切,你会领会到Grunt是多么的让人吃惊,体验一下他让人敬畏的力量,就像慵懒的沐浴在温暖的阳光下一样让人满意。
如果你还没有安装Node,NPM和Grunt 那就需要先安装好这些东西(真的不难也不可怕)安装好之后再继续往下看。
下面几点是我们想要Grunt为我们做的事情:
1.监听我们改变项目里的HTML,JS和Sass文件
2.编译Sass&compass
3.压缩并连接js文件
那我们往下继续。
什么是Grunt?
Grunt是一个JavaScript任务运行器(JavaScript task runner),它是用JavaScript(使用Node Js)编写,用来运行任务。Grunt使用两个文件——一个package.json(告诉Grunt他需要的所有依赖)和一个Gruntfile文件。如果你看了前一篇文章,在你项目文件夹里可能已经有了这两个文件。如果还没有那就去Github仓库下载或者fork。
Package JSON文件
这个 package.json文件一个NPM事情。我理解(或许不足)的是在你项目里,它是存储所有Node依赖的元数据。这篇文章对pasckge.json概述的不错。
安装一个Grunt插件
Grunt利用自动化插件运行任务。我们需要几个插件来实现文章顶部列出的5个目标。一个用来监听所有的修改,一个用来运行compass,一个用来连接/压缩我们的js文件,还需要一个做实时重载页面多设备的东西。
来到命令行。首先我们需要浏览项目
用这句命令:
$ cd path/to/my/project/folder
如果你在上面那条cd命令后面直接跟的你的项目路径(进入到你的项目目录),那么现在你就可以使用下面这条命令安装第一个插件了:grunt-contrib-watch
$ npm install grunt-contrib-watch --save-dev
这条命令将会输出一些让你觉得不爽的机器语言,但是你可以不用管它。当安装完成以后,去看看你的package.json文件。它应该有更新包含grunt-contrib-watch依赖这一小段文字:
{ // ... "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-watch": "~0.5.0" } }
现在回到命令行,一个一的重复下面命令安装这两个插件:
$ npm install grunt-contrib-compass --save-dev $ npm install grunt-contrib-uglify --save-dev
有点幸运哈,现在你已经有了项目需要的所有插件了。你的package.json文件也应该列出了所有这些插件的依赖(也可能还更多)。
Gruntfile文件
这个Gruntfile文件看起来有点想下面这样子:
module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON(‘package.json‘), // CONFIG (一些配置)===================================/ }); // DEPENDENT PLUGINS(依赖的插件) =========================/ grunt.loadNpmTasks(); // TASKS(任务) =====================================/ grunt.registerTask(‘default‘, []); };
这个Gruntfile分成3个主要的小节:
- Dependencies(依赖的插件)
- Tasks(运行的任务)
- Task configuration(任务配置)
设置这些配置并且选择把它作为你Gruntfile的第一部分,引入插件作为第二部分,然后告诉Grunt运行这些插件,按照每一个你配置的。通过在命令行输入“grunt”命令来完成这些任务,要么输入“grunt <task-name>”来运行指定的任务或者子任务。(<task-name>就是你要运行任务的任务名,例如你现在想要压缩css,并且它的任务名叫"cssmin",这时候你就在命令行输入 “grunt cssmin”)
现在首先让Gruntfile第一部分包含我们依赖的插件,找到“grunt.loadNpmTasks();
”这一行,复制整行然后粘贴3次,那就应该像这个样子:
// ... // DEPENDENT PLUGINS =========================/ grunt.loadNpmTasks(); grunt.loadNpmTasks(); grunt.loadNpmTasks(); // ... };
用引号包住插件名,添加到括号里,像这样
// ...
// DEPENDENT PLUGINS =========================/
grunt.loadNpmTasks(‘grunt-contrib-watch
’); grunt.loadNpmTasks(‘grunt-contrib-compass’); grunt.loadNpmTasks(‘grunt-contrib-compass’);
// ... };
接下来,配置watch任务,复制粘贴注释行下面的配置:
// CONFIGURATION =============================/ watch: { compass: { files: [‘**/*.{scss,sass}‘], tasks: [‘compass:dev‘] }, js: { files: [‘**/*.js‘], tasks: [‘uglify‘] } }, // ... };
上面我们是创建了一个watch任务,他的子任务是compass(指的是watch:compass)和js(watch:js)。配置watch:compass任务来监听以.scss或.sass后缀名结尾的文件。如果这些文件被修改之后,watch:compass任务将会执行“compass:dev”任务。配置js任务用来监听js文件,如果js文件被修改那么就会运行“uglify”任务。
Lets set up the Compass task. After the last closing bracket and comma of the watch task (follow the indentation) add the following:
现在我们来配置compass任务。在watch任务(跟这个一样的缩紧)的最后一个右大括号和逗号后面添加下面的代码:
compass: { dev: { options: { sassDir: [‘styles/sass‘], cssDir: [‘styles/css‘], environment: ‘development‘ } }, },
现在我们就配置好了compass任务,和一个叫dev的子任务(compass:dev),指明了sass目录和输出css的目录,配置环境为‘development‘(开发环境)。我们编译的时候还会用一些开发环境下默认的配置(像默认保持expanded格式输出css,默认添加行注释等等)。
现在我们本来只设置一个compass任务。这个选择块会在comass:{}的括号里。但是,我们想让comapss变的比现在更灵活一点。那就配置一个分开的production(生产环境)任务,编辑compass就像下面这样:
compass: { dev: { //... dev options here }, prod: { options: { sassDir: [‘styles/sass‘], cssDir: [‘styles/css‘], environment: ‘production‘ } }, },
现在我们可以调用compass:prod任务,编译sass文件然后以compressed (压缩)格式输出样式,为部署做好准备。
下面配置我们的uglify任务来连接/压缩js文件。在comapss任务后面,添加下面的代码:
uglify: { all: { files: { ‘js/min/main.min.js‘: [ ‘js/libs/jquery.js‘, ‘js/main.js‘ ] } }, },
当我们运行这个任务的时候,uglify将会得到方括号里列出来的所有文件,然后把他们压缩到一起。如果我们有一些HTML构建过程(例如使用一个静态网站生成器),在开发环境我们可能包括完整的脚本,然后运行上面压缩代码的方式来分开我们的prod任务——就像我们们在上面compass任务那样。
这种构建过程真的让Grunt熠熠生辉就像Codekit。你可以运行定制的dev任务和构建生产环境需要的,仅仅通过grunt prod命令。你甚至可以使用像Grunt git 部署或者Grunt FTP 部署一样并作为构建生产环境的一部分发送你的网站到服务器。我跑题了....
Default 任务
当我们开始Grunt的时候需要编译我们的css和js。我们也想运行我们的watch任务。为了这样,我们就使用default任务来触发。在你妹的Gruntfile中找到像下面的行:
grunt.registerTask(‘default‘, []);
Any tasks we want to run when we enter Grunt need to go between the square brackets. so add ‘compass:dev‘ , ‘uglify‘ , ‘watch‘
between the brackets (with quotes and comma seperated).
当我们进入Grunt想要运行的任何任务需要在这个方括号里。所以添加‘compass:dev‘ , ‘uglify‘ , ‘watch‘
在括号里(用引号和逗号分开)。
无论如何,让我们试一下到目前为止我们做的这些事情。现在到命令行来(确保在你的项目目录),输入grunt 后按enter键,然后你会看到:
Running "watch" task Waiting...Warning: EMFILE, too many open files
一遍一遍又一遍的,如果你喜欢你可以尝试着这样做,然后按ctrl+c退出进程。
原因是我们正在监听项目中的所有js文件。如果你去看一下node_modules文件夹,这是当我们安装所有node插件自动添加的,这里您将看到很多文件夹和大量的javascript文件。我们需要更多关于监听什么js文件的细节。更新你的watch任务:
watch: { compass: { files: [‘**/*.{scss,sass}‘], tasks: [‘compass:dev‘] }, js: { files: [‘js/**/*.js‘], // <== CHANGE HERE tasks: [‘uglify‘] } },
By adding the js folder, we can ensure Grunt isn‘t wasting time and energy watching millions of js files (unless you have millions of js files in your js folder - I don‘t recommend a million javascript files in your project)
Try running grunt now by going to your command line and entering “grunt”.
通过添加js文件夹,我们可以保证Grunt并没有浪费时间和精力来监听数以万计的js文件(除非你真的有成千上万的js文件在你项目中——我也不建议你项目你有成千上万的js文件)
现在,在里命令行里输入grunt来试一下运行它。
Running "compass:dev" (compass) task unchanged styles/sass/style.scss Compilation took 0.001s Running "uglify:all" (uglify) task File "JS/min/main.min.js" created. Running "watch" task Waiting...
刷刷刷!这些反馈信息对每个任务说明的非常好。现在它又在等待什么呢?哦,是在等待编译被改变的文件。那我们就去修改一个scss文件然后保存吧。现在来看看这个命令行,你可以看到下面这样:
Running "watch" task Waiting...OK >> File "styles/sass/style.scss" changed. Running "compass:dev" (compass) task remove .sass-cache/ remove styles/css/style.css create styles/css/style.css (0.009s) Compilation took 0.01s Done, without errors. Completed in 1.305s at Mon Sep 16 2013 22:31:48 GMT+0100 (BST) - Waiting...
现在可以在你的css文件里明显的看到刚才的修改!真不错!!!!
分离 Grunt 任务
The last thing we‘ll set up is a non-default task.
Now you can run any task in grunt by typing "grunt taskname:subtask" in the command line. For example to run our compass:prod task, we would enter:
最后,我们将构建一个非默认任务。
现在,在grunt里你可以运行任何一个任务,通过输入grunt taskname:subtask命令。例如运行compass:prod任务,我们输入:
$ grunt compass:prod
这样虽然很不错,但是,如果你有一个js文件需要为生产环境编译,或者像上面说的那样部署到ftp上面,想要在这同一时间运行,那这样在终端输入命令就会非常难处理。
在default任务行下面,输入下面这样的代码:
// PROD BUILD grunt.registerTask(‘prod‘, [‘compass:dev‘]);
这里我们创建一个自定义任务prod并且还添加了一个运行任务当它被执行的时候(我们的compass:prod任务)。像default任务一样运用了同样的规则来添加其他任务,按你想要运行的顺序从左到右的添加,用引号和逗号隔开。
现在我们去修改一下sass文件然后在终端运行这个命令:
$ grunt prod
如果所有都开始起作用,那会重新开始编译并把css文件压缩到一行
自动化工作 = 鸡尾酒
和我们已经做的。其实搭建所有只是一点点工作,但是大部分的事情已经做了并且下次也不需要很多很多时间。简单的扩展一下Gruntfile和package.json文件来满足你下一个项目的需求