转载:http://segmentfault.com/blog/laopopo/1190000000372547
http://javascript.ruanyifeng.com/tool/gulp.html
本文假设你之前没有用过任何任务脚本(task runner)和命令行工具,一步步教你上手Gulp。不要怕,它其实很简单,我会分为五步向你介绍gulp并帮助你完成一些惊人的事情。那就直接开始吧。
首先,最基本也最重要的是,我们需要搭建node环境。访问http://nodejs.org,然后点击大大的绿色的install
按钮,下载完成后直接运行程序,就一切准备就绪。npm会随着安装包一起安装,稍后会用到它。
也许现在你还不是很了解什么是命令行——OSX中的终端(Terminal),windows中的命令提示符(Command Prompt),但很快你就会知道。它看起来没那么简单,但一旦掌握了它的窍门,就可以很方便的执行很多命令行程序,比如Sass,Yeoman和Git等,这些都是非常有用的工具。
如果你很熟悉命令行,直接跳到步骤四。
为了确保Node已经正确安装,我们执行几个简单的命令。
node -v
回车(Enter),如果正确安装的话,你会看到所安装的Node的版本号,接下来看看npm。
npm -v
这同样能得到npm的版本号。
如果这两行命令没有得到返回,可能node就没有安装正确,尝试重启下命令行工具,如果还不行的话,只能回到第一步进行重装。
现在,我们已经大致了解了命令行并且知道如何简单使用它,接下来只需要两个简单的命令就能定位到文件目录并看看目录里都有些什么文件。
建议多敲敲这两个命令,了解文件系统并知道文件都在哪里。
习惯使用了这两个命令后,就要进入我们的项目目录,这个目录各不相同,举个例子,这是我进入我项目目录的命令:
cd /Applications/XAMPP/xamppfiles/htdocs/my-project
成功进入项目目录后,我们开始安装gulp。
我们已经知道如何使用命令行,现在尝试点新的东西,认识npm然后安装gulp。
NPM是基于命令行的node包管理工具,它可以将node的程序模块安装到项目中,在它的官网中可以查看和搜索所有可用的程序模块。
在命令行中输入
sudo npm install -g gulp
npm是安装node模块的工具,执行install命令
-g表示在全局环境安装,以便任何项目都能使用它
运行时注意查看命令行有没有错误信息,安装完成后,你可以使用下面的命令查看gulp的版本号以确保gulp已经被正确安装。
gulp -v
接下来,我们需要将gulp安装到项目本地
npm install —-save-dev gulp
这里,我们使用—-save-dev
来更新package.json文件,更新devDependencies
值,以表明项目需要依赖gulp。
Dependencies
可以向其他参与项目的人指明项目在开发环境和生产环境中的node模块依懒关系,想要更加深入的了解它可以看看package.json文档。
安装好gulp后我们需要告诉它要为我们执行哪些任务,首先,我们自己需要弄清楚项目需要哪些任务。
npm install gulp-jshint gulp-sass gulp-concat gulp-uglify gulp-rename --save-dev
提醒下,如果以上命令提示权限错误,需要添加
sudo
再次尝试。
现在,组件都安装完毕,我们需要新建gulpfile文件以指定gulp需要为我们完成什么任务。
gulp只有五个方法: task
,run
,watch
,src
,和dest
,在项目根目录新建一个js文件并命名为gulpfile.js,把下面的代码粘贴进去:
gulpfile.js
// 引入 gulp var gulp = require('gulp'); // 引入组件 var jshint = require('gulp-jshint'); var sass = require('gulp-sass'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var rename = require('gulp-rename'); // 检查脚本 gulp.task('lint', function() { gulp.src('./js/*.js') .pipe(jshint()) .pipe(jshint.reporter('default')); }); // 编译Sass gulp.task('sass', function() { gulp.src('./scss/*.scss') .pipe(sass()) .pipe(gulp.dest('./css')); }); // 合并,压缩文件 gulp.task('scripts', function() { gulp.src('./js/*.js') .pipe(concat('all.js')) .pipe(gulp.dest('./dist')) .pipe(rename('all.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); // 默认任务 gulp.task('default', function(){ gulp.run('lint', 'sass', 'scripts'); // 监听文件变化 gulp.watch('./js/*.js', function(){ gulp.run('lint', 'sass', 'scripts'); }); });
现在,分段解释下这段代码。
var gulp = require('gulp'); var jshint = require('gulp-jshint'); var sass = require('gulp-sass'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var rename = require('gulp-rename');
这一步,我们引入了核心的gulp和其他依赖组件,接下来,分开创建lint, sass, scripts 和 default这四个不同的任务。
gulp.task('lint', function() { gulp.src('./js/*.js') .pipe(jshint()) .pipe(jshint.reporter('default')); });
Link任务会检查js/
目录下得js文件有没有报错或警告。
gulp.task('sass', function() { gulp.src('./scss/*.scss') .pipe(sass()) .pipe(gulp.dest('./css')); });
Sass任务会编译scss/
目录下的scss文件,并把编译完成的css文件保存到/css
目录中。
gulp.task('scripts', function() { gulp.src('./js/*.js') .pipe(concat('all.js')) .pipe(gulp.dest('./dist')) .pipe(rename('all.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); });
scripts任务会合并js/
目录下得所有得js文件并输出到dist/
目录,然后gulp会重命名、压缩合并的文件,也输出到dist/
目录。
gulp.task('default', function(){ gulp.run('lint', 'sass', 'scripts'); gulp.watch('./js/*.js', function(){ gulp.run('lint', 'sass', 'scripts'); }); });
这时,我们创建了一个基于其他任务的default任务。使用.run()
方法关联和运行我们上面定义的任务,使用.watch()
方法去监听指定目录的文件变化,当有文件变化时,会运行回调定义的其他任务。
现在,回到命令行,可以直接运行gulp任务了。
gulp
这将执行定义的default任务,换言之,这和以下的命令式同一个意思
gulp default
当然,我们可以运行在gulpfile.js中定义的任意任务,比如,现在运行sass任务:
gulp sass
(Kimi: 哇塞,酷比了哎~)
现在已经做到了设置gulp任务然后运行他们,现在再回顾下之前学习的。
另外,有一些参考资源供进一步学习:
本文译自http://travismaynard.com/writing/getting-started-with-gulp
2.
来自《JavaScript 标准参考教程(alpha)》,by 阮一峰
Gulp与Grunt一样,也是一个自动任务运行器。它充分借鉴了Unix操作系统的管道(pipe)思想,很多人认为,在操作上,它要比Grunt简单。
Gulp需要全局安装,然后再在项目的开发目录中安装为本地模块。先进入项目目录,运行下面的命令。
npm install -g gulp
npm install --save-dev gulp
项目根目录中的gulpfile.js,是Gulp的配置文件。它大概是下面的样子。
var gulp = require('gulp'); gulp.task('default', function () { });
下面就是一个典型的gulpfile.js文件。
var gulp = require('gulp'), uglify = require('gulp-uglify'); gulp.task('minify', function () { gulp.src('js/app.js') .pipe(uglify()) .pipe(gulp.dest('build')) });
上面代码中使用了gulp-uglify模块。在此之前,需要先安装这个模块。
npm install --save-dev gulp-uglify
gulpfile.js加载gulp和gulp-uglify模块之后,使用gulp模块的task方法指定任务。task方法有两个参数,第一个是任务名,第二个是任务函数。在任务函数中,使用gulp模块的src方法,指定所要处理的文件,然后使用pipe方法,将上一步的输出转为当前的输入,进行链式处理。
在上面代码中,使用两次pipe方法,也就是说做了两种处理。第一种处理是使用gulp-uglify模块,压缩源码;第二种处理是使用gulp模块的dest方法,将上一步的输出写入本地文件,这里是build.js(代码中省略了后缀名js)。
从上面的例子中可以看到,gulp充分使用了“管道”思想,就是一个数据流(stream):src方法读入文件产生数据流,dest方法将数据流写入文件,中间是一些中间步骤,每一步都对数据流进行一些处理。
下面是另一个数据流的例子。
gulp.task('js', function () { return gulp.src('js/*.js') .pipe(jshint()) .pipe(uglify()) .pipe(concat('app.js')) .pipe(gulp.dest('build')); });
上面代码使用pipe命令,分别进行jshint、uglify、concat三步处理。
gulp模块的src方法,用于产生数据流。它的参数表示所要处理的文件,一般有以下几种形式。
src方法的参数还可以是一个数组,用来指定多个成员。
gulp.src(['js/**/*.js', '!js/**/*.min.js'])
gulp模块的task方法,用于定义具体的任务。它的第一个参数是任务名,第二个参数是任务函数。下面是一个非常简单的任务函数。
gulp.task('greet', function () { console.log('Hello world!'); });
task方法还可以指定按顺序运行的一组任务。
gulp.task('build', ['css', 'js', 'imgs']);
上面代码先指定build任务,它按次序由css、js、imgs三个任务所组成。注意,由于每个任务都是异步调用,所以没有办法保证js任务的开始运行的时间,正是css任务运行结束。
如果希望各个任务严格按次序运行,可以把前一个任务写成后一个任务的依赖模块。
gulp.task('css', ['greet'], function () { // Deal with CSS here });
上面代码表明,css任务依赖greet任务,所以css一定会在greet运行完成后再运行。
如果一个任务的名字为default,就表明它是“默认任务”,在命令行直接输入gulp命令,就会运行该任务。
gulp.task('default', function () { // Your default task });
gulp模块的watch方法,用于指定需要监视的文件。一旦这些文件发生变动,就运行指定任务。
gulp.task('watch', function () { gulp.watch('templates/*.tmpl.html', ['build']); });
上面代码指定,一旦templates目录中的模板文件发生变化,就运行build任务。
watch方法也可以用回调函数,代替指定的任务。
gulp.watch('templates/*.tmpl.html', function (event) { console.log('Event type: ' + event.type); console.log('Event path: ' + event.path); });
另一种写法是watch方法所监控的文件发生变化时(修改、增加、删除文件),会触发change事件。可以对change事件指定回调函数。
var watcher = gulp.watch('templates/*.tmpl.html', ['build']); watcher.on('change', function (event) { console.log('Event type: ' + event.type); console.log('Event path: ' + event.path); });
除了change事件,watch方法还可能触发以下事件。
watcher对象还包含其他一些方法。
一般情况下,gulpfile.js中的模块需要一个个加载。
var gulp = require('gulp'), jshint = require('gulp-jshint'), uglify = require('gulp-uglify'), concat = require('gulp-concat'); gulp.task('js', function () { return gulp.src('js/*.js') .pipe(jshint()) .pipe(jshint.reporter('default')) .pipe(uglify()) .pipe(concat('app.js')) .pipe(gulp.dest('build')); });
上面代码中,除了gulp模块以外,还加载另外三个模块。
这种一一加载的写法,比较麻烦。使用gulp-load-plugins模块,可以加载package.json文件中所有的gulp模块。上面的代码用gulp-load-plugins模块改写,就是下面这样。
var gulp = require('gulp'), gulpLoadPlugins = require('gulp-load-plugins'), plugins = gulpLoadPlugins(); gulp.task('js', function () { return gulp.src('js/*.js') .pipe(plugins.jshint()) .pipe(plugins.jshint.reporter('default')) .pipe(plugins.uglify()) .pipe(plugins.concat('app.js')) .pipe(gulp.dest('build')); });
上面代码假设package.json文件包含以下内容。
{ "devDependencies": { "gulp-concat": "~2.2.0", "gulp-uglify": "~0.2.1", "gulp-jshint": "~1.5.1", "gulp": "~3.5.6" } }
gulp-livereload模块用于自动刷新浏览器,反映出源码的最新变化。它除了模块以外,还需要在浏览器中安装插件,用来配合源码变化。
var gulp = require('gulp'), less = require('gulp-less'), livereload = require('gulp-livereload'), watch = require('gulp-watch'); gulp.task('less', function() { gulp.src('less/*.less') .pipe(watch()) .pipe(less()) .pipe(gulp.dest('css')) .pipe(livereload()); });
上面代码监视less文件,一旦编译完成,就自动刷新浏览器。