初学gulp

Gulp是一个工具,可以帮助您处理Web开发时的几项任务。 它常常用于执行前端任务,如:
  1. 旋转网络服务器
  2. 保存文件时自动重新加载浏览器
  3. 使用像Sass或LESS这样的预处理器
  4. 优化资源,如CSS,JavaScript和图像
这不是Gulp可以做的事情的全面列表。 如果你疯了,你甚至可以用Gulp建立一个静态的站点生成器(我已经完成了!)。 所以是的,Gulp是非常强大的,但如果你想创建自己的定制的构建过程,你将不得不学习如何使用Gulp。

这就是本文的内容。 它可以帮助你获得如此好的Gulp的基础知识,你可以开始自己探索一切。

在我们开始使用Gulp之前,让我们来谈谈为什么你可能想使用Gulp而不是其他类似的工具。

为什么是gulp?

Gulp等工具通常被称为“构建工具”,因为它们是用于运行构建网站的任务的工具。 现在两个最受欢迎的构建工具是Gulp和Grunt。 (Chris在这里开始Grunt的帖子)。 但当然还有其他的。 Broccoli 专注于资产编制,最常见的构建工具任务之一。
已经有多篇文章涵盖了Grunt和Gulp之间的区别,以及为什么你可以使用另一个。 你可以查看 这篇文章, 这个,或者如果你有兴趣了解更多。 Brunch 在关注资产方面类似,它捆绑在一些最常见的其他任务,如服务器和文件监视器。
主要区别在于如何配置工作流。 与Grunt相比,Gulp配置趋向于更短和更简单。 Gulp也往往跑得更快。
现在我们来看看如何使用Gulp设置工作流程。

我们需要设置什么?

在本文末尾,您将有一个工作流完成本文开头概述的任务:
  1. 旋转Web服务器
  2. 将Sass编译成CSS
  3. 保存文件时自动刷新浏览器
  4. 优化所有资源(CSS,JS,字体和图像)进行生产
  5. 您还将学习如何将不同任务链接到易于理解和执行的简单命令中。
我们先从您的计算机上安装Gulp。

安装gulp

在安装Gulp之前,您需要将Node.js(Node)安装到计算机上。
如果您没有安装Node,您可以从Node的网站下载软件包安装程序。
完成安装Node后,可以通过在命令行中使用以下命令来安装Gulp:
$ sudo npm install gulp -g

我们在这里使用的npm install命令是一个使用Node Package Manager(npm)将Gulp安装到计算机上的命令。
该命令中的-g标志告诉npm将Gulp全局安装到您的计算机上,这允许您在系统的任何位置使用gulp命令。
Mac用户在命令中需要额外的sudo关键字,因为他们需要管理员权限才能在全球安装Gulp。
现在你已经安装了Gulp,我们来做一个使用Gulp的项目。

新建gulp项目

首先,我们将在本教程中创建一个名为project作为项目根目录的文件夹。 从该目录中运行npm init命令:
$ npm init
npm init命令为项目创建一个package.json文件,该文件存储有关项目的信息,如项目中使用的依赖项(Gulp是依赖关系的示例)。
npm init将提示您: 初学gulp_第1张图片
一旦创建了package.json文件,我们可以使用以下命令将Gulp安装到项目中:
$ npm install gulp --save-dev
这一次,我们正在将Gulp安装到项目中,而不是在全局安装,这就是为什么命令有一些区别。
您将看到sudo关键字不是必需的,因为我们不是全局安装Gulp,所以-g也不是必需的。 我们添加了--save-dev,它告诉计算机在package.json中添加gulp作为dev的依赖。 初学gulp_第2张图片
如果在命令执行完成后检查项目文件夹,应该会看到Gulp已经创建了一个node_modules文件夹。 您还应该在node_modules中看到一个gulp文件夹。
初学gulp_第3张图片

我们准备使用Gulp工作。 在我们这样做之前,我们必须清楚我们将如何使用Gulp进行项目,其中一部分是决定一个目录结构。

确定文件夹结构

Gulp具有足够的灵活性,能够处理任何文件夹结构。 在调整项目之前,您只需要了解内部工作。
对于本文,我们将使用通用webapp的结构:
初学gulp_第4张图片
在这种结构中,我们将使用该应用程序文件夹进行开发,而dist(如“distribution”)文件夹用于包含生产站点的优化之后的文件。
由于应用程序用于开发目的,所有我们的代码将被放置在应用程序中。
当我们的Gulp配置工作时,我们必须记住这个文件夹结构。 现在,我们开始在gulpfile.js中创建您的第一个Gulp任务,它存储所有Gulp配置。

写你的第一个gulp任务

使用Gulp的第一步是在gulpfile中引入它。
var gulp = require('gulp');
require语句告诉Node来查看一个名为gulp的包的node_modules文件夹。 找到包后,我们将其内容分配给变量gulp。
我们现在可以开始用这个gulp变量写一个gulp任务。 gulp任务的基本语法是:
gulp.task('task-name', function() {
  // Stuff here
});
task-name指的是任务的名称,当您要在Gulp中运行任务时,该名称将被使用。 您还可以通过编写gulp task-name在命令行中运行相同的任务。
要测试出来,让我们创建一个Hello Zell!的Hello任务。
gulp.task('hello', function() {
  console.log('Hello Zell');
});
我们可以在命令行中使用gulp hello来运行这个任务。
$ gulp hello
命令行将返回一个“Hello Zell!”的日志。
初学gulp_第5张图片
Gulp任务通常比这更复杂一些。 它通常包含两个额外的Gulp方法,加上各种Gulp插件。
这是一个真正的任务可能是什么样子:
gulp.task('task-name', function () {
  return gulp.src('source-files') // Get source files with gulp.src
    .pipe(aGulpPlugin()) // Sends it through a gulp plugin
    .pipe(gulp.dest('destination')) // Outputs the file in the destination folder
})
正如你所看到的,一个真正的任务需要两个额外的gulp方法 - gulp.src和gulp.dest。
gulp.src告诉Gulp任务用于任务的文件,而gulp.dest告诉Gulp在任务完成之后输出文件。
我们尝试构建一个真正的任务,我们将Sass文件编译成CSS文件。

用Gulp进行预处理

我们可以借助一个名为gulp-sass的插件,将Sass编译成Gulp中的CSS。 您可以使用npm安装命令(如我们为gulp)安装gulp-sass到您的项目。
我们还想使用--save-dev标志来确保gulp-sass被添加到package.json中的devDependencies中。
$ npm install gulp-sass --save-dev
我们需要从node_modules文件夹中使用gulp-sass,就像我们用gulp一样,我们可以使用该插件。
var gulp = require('gulp');
// Requires the gulp-sass plugin
var sass = require('gulp-sass');
我们可以用sass()替换aGulpPlugin()来使用gulp-sass。 由于任务是将Sass编译成CSS,所以我们来命名为sass。
gulp.task('sass', function(){
  return gulp.src('source-files')
    .pipe(sass()) // Using gulp-sass
    .pipe(gulp.dest('destination'))
});
我们需要提供sass任务的源文件和任务的目的地,所以让我们在app / scss文件夹中创建一个styles.scss文件。 该文件将被添加到gulp.src中的sass任务。
我们要将最终的styles.css文件输出到`app / css`文件夹,这将是gulp.dest的目的地。
gulp.task('sass', function(){
  return gulp.src('app/scss/styles.scss')
    .pipe(sass()) // Converts Sass to CSS with gulp-sass
    .pipe(gulp.dest('app/css'))
});
我们将要测试这个sass任务是否按照我们想要的方式工作。 为此,我们可以在styles.scss中添加一个Sass函数。
// styles.scss
.testing {
  width: percentage(5/7);
}
如果在命令行中运行gulp sass,现在应该可以看到在app / css中创建了一个styles.css文件。 另外,它的代码中的百分比(5/7)被评估为71.42857%。
/* styles.css */
.testing {
  width: 71.42857%; 
}
这就是我们知道sass任务的工作原理!
有时我们需要同时编译多个.scss文件到CSS中。 我们可以在Node glob的帮助下这样做。
FYI:Gulp-sass使用LibSass将Sass转换为CSS。 它比基于Ruby的方法要快得多。 如果需要,您还可以使用gulp-ruby-sass或gulp-compass替代Gulp的Ruby方法。

使用通配符

Globs是匹配的文件模式,允许您将多个文件添加到gulp.src中。 这就像正则表达式,但是专门用于文件路径。
当您使用glob时,计算机将检查指定模式的文件名和路径。 如果模式存在,则匹配文件。
大多数Gulp的工作流程往往只需要4种不同的globbing模式:
  1. * .scss:*模式是与当前目录中的任何模式匹配的通配符。 在这种情况下,我们将根文件夹(项目)中匹配任何以.scss结尾的文件。
  2. ** / *.scss:这是一个更加极端的版本的*模式,匹配任何文件以.scss结尾的根文件夹和任何子目录。
  3. !not-me.scss:! 表示Gulp应该从匹配中排除模式,如果您必须从匹配的模式中排除文件,这将非常有用。 在这种情况下,not-me.scss将被排除在比赛之外。
  4. *.+(scss | sass):plus +和括号()允许Gulp匹配多个模式,不同的模式由管道隔开| 字符。 在这种情况下,Gulp将匹配根文件夹中以.scss或.sass结尾的所有文件。
由于我们现在知道globbing,所以我们可以用scss / ** / * .scss模式替换app / scss / styles.scss,它与app / scss或子目录中的.scss扩展名匹配。
gulp.task('sass', function() {
  return gulp.src('app/scss/**/*.scss') // Gets all files ending with .scss in app/scss and children dirs
    .pipe(sass())
    .pipe(gulp.dest('app/css'))
})
在app / scss中找到的任何其他Sass文件将自动被包含在具有此更改的sass任务中。 如果将print.scss文件添加到项目中,您将看到print.css将在app / css中生成。
初学gulp_第6张图片
我们现在可以使用单个命令将所有Sass文件编译成CSS文件。 问题是,如果我们每次要将Sass编译成CSS,都需要手动运行gulp sass,该怎么办?
幸运的是,只要通过称为“观看”的过程保存文件,我们就可以告诉Gulp自动运行sass任务。

监控变化的sass文件

Gulp为我们提供了一种监视方法,以检查文件是否已保存。 watch方法的语法是:
// Gulp watch syntax
gulp.watch('files-to-watch', ['tasks', 'to', 'run']); 
如果我们想要保存所有Sass文件并运行sass任务,那么我们只需要使用app / scss / ** / * .scss和['tasks',' to','run'] :
// Gulp watch syntax
gulp.watch('app/scss/**/*.scss', ['sass']); 
更多的时候,我们会一次看多种类型的文件。 为此,我们可以将多个监视进程分组到一个监视任务中:
gulp.task('watch', function(){
  gulp.watch('app/scss/**/*.scss', ['sass']); 
  // Other watchers
})
如果您现在运行gulp watch命令,您会看到Gulp立即开始
初学gulp_第7张图片
并且每当保存.scss文件时,它都会自动运行sass任务。

优化CSS和JavaScript文件

当我们尝试优化CSS和JavaScript文件进行生产时,开发人员有两个任务要执行:分组和连接。
开发人员在自动执行此过程时遇到的一个问题是,很难以正确的顺序连接您的脚本。
假设我们在index.html中包含3个脚本标签。

  
  
  
  
这些脚本位于两个不同的目录中。 将它们与传统的插件(如gulp-concatenate)连接是很困难的。
幸运的是,有一个有用的Gulp插件,gulp-useref解决了这个问题。
Gulp-useref通过查找以“<! - build:”开头的注释,将任意数量的CSS和JavaScript文件连接到一个文件中,并以“<! - endbuild - >”结尾。 其语法是:

... HTML Markup, list of script / link tags.
可以是js,css或remove。 最好将类型设置为要连接的文件类型。 如果设置要删除的类型,Gulp将删除整个构建块而不生成文件。
这里指的是生成文件的目标路径。
我们希望在js文件夹中生成最终的JavaScript文件,如main.min.js. 因此,标记将是:




现在让我们在gulpfile中配置gulp-useref插件。 我们必须安装插件,并在gulpfile中引入它。
$ npm install gulp-useref --save-dev
var useref = require('gulp-useref');
设置用户任务类似于我们迄今为止完成的其他任务。 以下是代码:
gulp.task('useref', function(){
  return gulp.src('app/*.html')
    .pipe(useref())
    .pipe(gulp.dest('dist'))
});
现在,如果你运行这个useref任务,Gulp将运行3脚本标签,并将它们连接成dist / js / main.min.js。
初学gulp_第8张图片
然而,这个文件现在还没有被细化。 我们必须使用gulp-uglify插件来帮助缩小JavaScript文件。 我们还需要一个名为gulp-if的第二个插件,以确保我们只尝试缩小JavaScript文件。
$ npm install gulp-uglify --save-dev 

// Other requires...
var uglify = require('gulp-uglify');
var gulpIf = require('gulp-if');

gulp.task('useref', function(){
  return gulp.src('app/*.html')
    .pipe(useref())
    // Minifies only if it's a JavaScript file
    .pipe(gulpIf('*.js', uglify()))
    .pipe(gulp.dest('dist'))
});

当您运行useref任务时,Gulp现在应该自动缩小“main.min.js”文件。
我还没有用Gulp-useref来揭示一件很好的事情:它会自动将“<! - build:”和“<! - endbuild - >”中的所有脚本更改为一个单一的JavaScript文件,即JS/ main.min.js`。
初学gulp_第9张图片
Wonderful, isn't it?
我们可以使用相同的方法连接任何CSS文件(如果您决定添加多个)。 我们将遵循相同的过程并添加构建注释。




我们也可以缩小连接的CSS文件。 我们需要使用一个名为gulp-cssnano的插件来帮助我们进行细化。
$ npm install gulp-cssnano

var cssnano = require('gulp-cssnano');

gulp.task('useref', function(){
  return gulp.src('app/*.html')
    .pipe(useref())
    .pipe(gulpIf('*.js', uglify()))
    // Minifies only if it's a CSS file
    .pipe(gulpIf('*.css', cssnano()))
    .pipe(gulp.dest('dist'))
});

现在,当您运行useref任务时,您将获得一个优化的CSS文件和一个优化的JavaScript文件。
接下来让我们继续优化图像。

优化图像

你现在已经猜到了 我们需要使用gulp-imagemin来帮助我们优化图像。
$ npm install gulp-imagemin --save-dev

var imagemin = require('gulp-imagemin');
在gulp-imagemin的帮助下,我们可以缩小png,jpg,gif甚至svg。 让我们为这个优化过程创建一个图像任务。
gulp.task('images', function(){
  return gulp.src('app/images/**/*.+(png|jpg|gif|svg)')
  .pipe(imagemin())
  .pipe(gulp.dest('dist/images'))
});

由于不同的文件类型可以进行不同的优化,您可能需要为imagemin添加选项以自定义每个文件的优化方式。
例如,您可以通过将隔行选项键设置为true来创建隔行扫描GIF。
gulp.task('images', function(){
  return gulp.src('app/images/**/*.+(png|jpg|jpeg|gif|svg)')
  .pipe(imagemin({
      // Setting interlaced to true
      interlaced: true
    }))
  .pipe(gulp.dest('dist/images'))
});

如果你想要也可以玩其他选项。
然而,优化图像是一个非常慢的过程,除非必要,否则您不想重复。 为此,我们可以使用gulp-cache插件。
$ npm install gulp-cache --save-dev

var cache = require('gulp-cache');

gulp.task('images', function(){
  return gulp.src('app/images/**/*.+(png|jpg|jpeg|gif|svg)')
  // Caching images that ran through imagemin
  .pipe(cache(imagemin({
      interlaced: true
    })))
  .pipe(gulp.dest('dist/images'))
});
我们几乎完成了优化过程。 还有一个文件夹,我们需要从`app`目录转换成`dist`,这是fonts目录。 现在我们来做

将字体复制到Dist

由于字体文件已经被优化,我们还没有做任何事情。 我们所要做的就是将字体复制到dist中。
我们可以通过gulp.src和gulp.dest指定Gulp来复制文件,而无需任何插件。
gulp.task('fonts', function() {
  return gulp.src('app/fonts/**/*')
  .pipe(gulp.dest('dist/fonts'))
})

现在Gulp会在运行gulp字体时将`fonts`从`app`复制到`dist`。 初学gulp_第10张图片
我们现在在gulpfile中有6个不同的任务,每个任务都必须单独使用命令行调用,这有点麻烦,所以我们想将所有内容都绑定成一个命令。
在我们这样做之前,我们来看看如何自动清理生成的文件。

自动清理生成的文件

由于我们自动生成文件,所以我们希望确保不再使用的文件不会保留在任何地方,除非我们知道。
这个过程称为清理(或简单的说,删除文件)。
我们必须使用del来帮助我们清洁。
npm install del --save-dev

var del = require('del');

del函数接收一个节点glob数组,告诉它要删除哪些文件夹。
gulp.task('clean:dist', function() {
  return del.sync('dist');
})

现在,Gulp会在gulp clean:dist运行时删除`dist`文件夹。
注意:我们不必担心删除dist / images文件夹,因为gulp-cache已经存储本地系统上的图像缓存。
要清除本地系统上的缓存,您可以创建一个名为“cache:clear”的单独任务
gulp.task('cache:clear',function(callback){
返回cache.clearAll(回调)
})
噢,那是一口气。 我们现在把我们所有的任务结合在一起!

组合Gulp任务

我们来总结一下我们做了什么 到目前为止,我们已经创建了两个不同的Gulp任务。
第一组是一个开发过程,我们将Sass编译成CSS,观察更改,并相应地重新加载浏览器。
第二套是一个优化过程,我们为生产网站准备好所有文件。 我们在此过程中优化了CSS,JavaScript和图像等资源,并将字体从应用程序复制到dist。
我们已经将第一组任务组合成一个简单的工作流程,使用gulp watch命令:
gulp.task('watch', ['browserSync', 'sass'], function (){
  // ... watchers
})

第二组包括我们需要运行以创建生产网站的任务。 这包括clean:dist,sass,useref,图像和字体。
如果我们走同样的思路,我们可以创建一个构建任务,将所有的东西结合在一起。
gulp.task('build', [`clean`, `sass`, `useref`, `images`, `fonts`], function (){
  console.log('Building files');
})

不幸的是,我们无法以这种方式编写构建任务,因为Gulp同时激活了第二个参数中的所有任务。
在清洁之前,有可能使用,图像甚至字体完成,这意味着整个“dist”文件夹被删除。
因此,为了确保清理在其余任务之前完成,我们需要使用一个额外的插件,称为“运行顺序”。
$ npm install run-sequence --save-dev

以下是运行序列的任务序列的语法:
var runSequence = require('run-sequence');

gulp.task('task-name', function(callback) {
  runSequence('task-one', 'task-two', 'task-three', callback);
});

当task-name被调用时,Gulp将首先运行任务。 当任务一完成时,Gulp将自动启动任务二。 最后,当任务二完成时,Gulp将运行任务三。
运行顺序还允许您同时运行任务,如果将它们放在数组中:
gulp.task('task-name', function(callback) {
  runSequence('task-one', ['tasks','two','run','in','parallel'], 'task-three', callback);
});

在这种情况下,Gulp首先运行任务一。 当任务一完成时,Gulp同时运行第二个参数中的每个任务。 必须在运行任务三之前完成此第二个参数中的所有任务。
所以我们现在可以创建一个任务,确保clean:dist首先运行,其次是所有其他任务:
gulp.task('build', function (callback) {
  runSequence('clean:dist', 
    ['sass', 'useref', 'images', 'fonts'],
    callback
  )
})

为了使事情保持一致,我们还可以与第一组建立相同的顺序。 我们这次使用default作为任务名称:
gulp.task('default', function (callback) {
  runSequence(['sass','browserSync', 'watch'],
    callback
  )
})

为什么默认 因为当你有一个名为default的任务时,可以通过键入gulp命令来运行它,这样可以节省一些按键。
最后,这是我们所做的所有工作的 github仓库

你可能感兴趣的:(初学gulp)