# 三、观察更新

前一章完全是关于狼吞虎咽的谋生之道:任务。本章将讲述当文件或文件夹改变时的反应，然后相应地采取行动。这给了她相当大的力量，并使某些场景对开发人员来说更容易，这样她就可以更专注于工作，而不会被重复的步骤分散注意力。

在开发您的网站或 web 应用时，您知道在浏览器中看到您的更改之前，您必须进行一些手动操作。即使大口已经让任务变得更容易，它仍然需要一些手动干预，比如打开一些外壳，键入一个命令，比如大口生成宏文件。

如果我们能跳过这一部分，让大口自己解决问题，那不是很好吗？欢迎来到大口看 API。

我们将从简单开始，将下一个代码基于代码清单 5，我们在第 2 章中看到了它。它将被改变以满足我们的目标:更少的重复工作和自动化一个吞咽任务。在一个名为第 3 章的文件夹中，我将它放在与第 2 章文件夹相同的级别，创建了一个新的**gulf file . js**文件，并将代码清单 11 中的代码放入其中。同时创建一个名为**资源**的子文件夹，在其中放置一个**。少了**文件，如下代码所示:

代码清单 13:观察文件

```js
  "use
  strict";

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

  gulp.task('watchLessFiles', function () {

  gulp.watch('./Assets/styles.less', function (event) {

  console.log('Watching
  file ' + event.path + ' being ' + event.type + ' by gulp.');

  })
  });

  gulp.task('default', ['watchLessFiles']);

```

代码清单 14:一个简单的。较少文件:/资产/样式。较少

```js
  @color:#b6ff00;
  @backcolor:#808080;

  body {

  background-color: @backcolor;
  }

  a {

   color: @color;

  &:hover {

  color: @color + @backcolor;

  }
  }

```

不要忘记安装所需的大口插件:

npm 安装大口-保存-开发

npm 安装无吞咽保存开发

现在运行默认的大口任务来启动观察任务。结果如下图所示。

![](img/00015.jpeg)

图 12

现在正在监视“资源”文件夹中的文件。为了测试这一点，在文本编辑器中打开**无样式**文件，并在其中键入一个额外的空格。现在保存它，并再次查看图 13 中的输出。

![](img/00016.jpeg)

图 13:被监视的文件被更改和保存后的输出

event.path 显示了我们正在观看的文件的路径，而 event.type 正确地向我们显示了输出**改变了**。其他可能的类型是**增加**或**删除**。

很高兴看到一些文件在保存时发生了变化，但是我们谈到了自动化。在这种情况下，它是经过处理的。我们感兴趣的. css 文件。要做到这一点，只需稍微更改一下**gulf file . js**文件:

代码清单 15:处理。将较少的文件转换为. css 文件/gulf file . js

```js
  "use
  strict";

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

  gulp.task('lessToCss', function () {

  gulp.src('Assets/Styles.less')

  .pipe(less())

  .pipe(gulp.dest('wwwroot/css'));
  });

  gulp.task('watchLessFiles', function () {

  gulp.watch('./Assets/styles.less', ['lessToCss']);
  });

  gulp.task('default', ['watchLessFiles']);

```

再次运行吞咽，更改**无样式**文件，并保存。这样做几次，每次。较少的文件被保存，正如我们在输出中看到的:

![](img/00017.jpeg)

图 14:重复保存。每次运行任务越少，文件越少

这无疑节省了宝贵的时间。为此，我们需要更改文件，保存它，自己运行任务 lessToCss，在这个过程中，离开我们的文本编辑器。

要停止这个过程，你可以简单地使用键盘组合 **Ctrl + C** 。要再次开始观看，只需再次运行默认的大口任务。

![](img/00018.jpeg)

图 15:对的重复更改。制作了更少文件

在上一节中，我们看到了如何观看文件并在保存时采取行动。这很好，但是当我们可以对整个文件夹进行这种操作时，这就变得非常有趣了。我们可以稍微修改一下代码，加入一个变量。这将保存路径，因此我们不必每次都键入它，并且可能会因键入错误而出错。

修改后的代码现在如下所示:

代码清单 16:处理。更少的文件进入。css 文件/gulf file . js

```js
  "use
  strict";

  var gulp = require('gulp');
  var less = require('gulp-less');
  var lessPath = './Assets/**/*.less';

  gulp.task('lessToCss', function () {

  gulp.src(lessPath)

  .pipe(less())

  .pipe(gulp.dest('wwwroot/css'));
  });

  gulp.task('watchLessFiles', function () {

  gulp.watch(lessPath, ['lessToCss']);
  });

  gulp.task('default', ['watchLessFiles']);

```

变量 lessPath 使用了 glob 符号 Assets/**/*.less。这是一种强大的编写方式，因为它的意思是“获取全部”。减少直接位于“资源”文件夹下的文件，以及“资源”文件夹子文件夹中的文件。”因此，您不必为每个子文件夹编写一个路径并遍历它，而是有机会以一种单一、紧凑的方式编写它。

如果我们运行代码并更改一些。更少的文件(直接在资产文件夹或任何子文件夹下)，我们保存它。文件越少，任务越少运行任务，输出被写入 wwwroot/css 文件夹，并考虑到 Assets 文件夹下的子文件夹。

![](img/00019.jpeg)

图 16:查看多个文件和文件夹

如果你尝试添加一个新的。减少文件并保存它…什么都不会发生。但是，如果您要更改一个在添加手表之前已经存在的. less 文件，新的。较少的文件也会被转换成. css 文件。后者是显而易见的，但我们希望它也能适用于新文件。

在前一节中，我们注意到在手表已经设置好之后添加的新文件不会运行。grave 的手表功能强大，但不是万能的。它会尽最大努力，但如果我们计划添加新文件，我们需要更强大的东西。

更强的东西以插件的形式出现:大口看。要获得它，只需运行熟悉的命令 npm install - save-dev 大口-watch。

因为它是一个插件，我们需要稍微重写我们的代码，因为它需要插入到流中才能工作。代码如下所示:

代码清单 17:利用吞咽观察插件

```js
  "use
  strict";

  var gulp = require('gulp');
  var less = require('gulp-less');
  var gulpWatch = require('gulp-watch');

  var lessPath = './Assets/**/*.less';

  gulp.task('lessToCss', function () {

  gulp.src(lessPath)

  .pipe(gulpWatch(lessPath))

  .pipe(less())

  .pipe(gulp.dest('wwwroot/css'));
  });

  gulp.task('default', ['lessToCss']);

```

现在运行大口默认任务，并尝试添加一个新的。在**/资产**文件夹中减少文件。您会注意到在 wwwroot/css 文件夹中会有一个新的。css 文件。

下面的过程是 web 开发人员所熟悉的:您在文件中进行一些更改，保存它，也许您用 Gulp 执行一些构建步骤，然后重新加载浏览器以查看前几个步骤的结果。大多数网页开发人员或设计人员甚至不再去想它，只需在 Mac 上按 Ctrl + F5，或 Command + R。

如果我们能摆脱其中的一些步骤，那就太好了。好吧，有了一个方便的插件，比如大口连接，你可以走很长的路。还有其他的选择，比如 glove-livereload，但是那个依赖于一个需要安装在你的浏览器中的插件。

此时，确保您已经安装了所有需要的模块(大口、无大口、大口玉和大口连接)。

对于这个例子，我们将使用 Jade 来生成 HTML 页面，Less 来生成 CSS 样式表、大口任务和观察者，当然还有大口连接插件。在添加重装功能之前，让我们为这个小项目创建一个最小的版本。布局如下:

![](img/00020.jpeg)

图 17:项目文件夹和文件结构

| ![](img/00021.gif) | 注意:gulpfile.js 和 package.json 是直接在 LiveReload 文件夹下，而不是 node_modules 子文件夹下。《崇高的文本》中使用的钴 2 主题可能会给人这种印象。Gulpfile.js 和 package.json 总是直接位于项目的根文件夹下。 |

**index.jade** 文件如下所示:

代码清单 18: /Assets/Jade/index.jade

```js
  doctype
  html
  html
        head
              title
  Hello world
              link(rel="stylesheet",
  href="css/styles.css")
        body
              h1
  gulp is great
              p
  it seems like it's working
              script(src="js/main.js")

```

较少的文件如下所示:

代码清单 19: /Assets/Less/colors.less

```js
  @color1: #c9c9c9;
  @color2: #e3e3e3;
  @color3: #9ad3de;
  @color4: #89bdd3;

```

代码清单 20:/Assets/Less/style . Less

```js
  @import "colors.less";

  body {
        color: @color1;
        background-color: @color4;
  }

  h1 {
        color: @color2;
        background-color: @color3;
  }

```

和 gulpfile.js:

代码清单 21:/gulf file . js

```js
  "use
  strict";

  var gulp = require('gulp'),
        less
  = require('gulp-less'),
        jade
  = require('gulp-jade'),
        connect
  = require('gulp-connect');

  var jadeDir = './Assets/Jade/**/*.jade';
  var lessDir = './Assets/Less/**/*.less';
  var outputDirHtml = './';
  var outputDirCss = './css/';

  gulp.task('jade', function () {

  gulp.src(jadeDir)
              .pipe(jade())
              .pipe(gulp.dest(outputDirHtml))
  });

  gulp.task('less', function () {

  gulp.src(lessDir)
              .pipe(less())
              .pipe(gulp.dest(outputDirCss));
  });

  gulp.task('watch', function () {

  gulp.watch([jadeDir], ['jade']);

  gulp.watch([lessDir], ['less']);
  })

  gulp.task('default', ['jade', 'less', 'watch']);

```

从终端运行大口命令可以确保在 watch 任务在输入文件上添加熟悉的 watch 时生成 index.html 和 css 文件。尝试更改翡翠或更少的文件，看看它得到更新。

现在打开一个浏览器，在**index.html**页面打开。在 **index.jade** 文件中更改一些内容，保存它，并刷新浏览器以查看更改。

是时候让魔法进来了。将 gulpfile.js 更改为以下内容:

代码清单 22:带有 livereload 功能的 gulf file . js-/gulf file . js

```js
  "use
  strict";

  var gulp = require('gulp'),
        less
  = require('gulp-less'),
        jade
  = require('gulp-jade'),
        connect
  = require('gulp-connect');

  var jadeDir = './Assets/Jade/**/*.jade';
  var lessDir = './Assets/Less/**/*.less';
  var outputDirHtml = './';
  var outputDirCss = './css/';

  gulp.task('jade', function () {

  gulp.src(jadeDir)
              .pipe(jade())
              .pipe(gulp.dest(outputDirHtml))
              .pipe(connect.reload());
  });

  gulp.task('less', function () {

  gulp.src(lessDir)
              .pipe(less())
              .pipe(gulp.dest(outputDirCss))
              .pipe(connect.reload());
  });

  gulp.task('watch', function () {

  gulp.watch([jadeDir], ['jade']);

  gulp.watch([lessDir], ['less']);
  })

  gulp.task('connect', function () {

  connect.server({

  root: './',

  livereload: true

  });
  });

  gulp.task('default', ['jade', 'less', 'watch', 'connect']);

```

另一个需要添加的重要代码，也是一个很容易被忽略的代码，是每当 Jade 文件或 Less 文件被更改时都需要重新加载的调用:。pipe(connect . reload())；。在玉少的任务中，一定要触发一次重装。建筑物运行更新后，它被触发，浏览器同时重新加载。运行吞咽命令，将出现以下内容:

![](img/00022.jpeg)

图 18: LiveReload

首先，它将执行任务，将 Jade 文件解析为 HTML，将 Less 文件解析为 CSS，并在前两者上添加观察器。它还将执行连接任务。在该任务中，设置了根 URL，并且应该打开实时重新加载选项。您需要明确地这样做；否则，它不会起作用。

输出的最后两行显示了导航到的位置: [http://localhost:8080](http://localhost:8080) 。大口连接插件提供了一个内置的服务器，在这个例子中我们需要它。

打开选择的浏览器，冲浪至[http://localhost:8080/index . html](http://localhost:8080/index.html)。您将看到如下页面:

![](img/00023.jpeg)

图 19:玉少任务运行后的初步结果

由于运行了 jade 和较少的任务，这些任务的输出为我们的解决方案增加了文件:

![](img/00024.jpeg)

图 20:玉少任务运行后的解决方案

现在是最酷的部分。当您在 Jade 或 Less 文件中更改内容时，请将浏览器保持在屏幕的可见范围内。保存后，您将在浏览器中看到即时更新。在这个演示中，我选择在相应的 colors.less 文件中更改颜色。

![](img/00025.jpeg)

图 21:无颜色文件被更改和保存

这样做的原因是大口连接在 HTML 中注入了一点额外的 JavaScript。通过使用浏览器的 F12 工具，我们可以轻松看到以下内容:

![](img/00026.jpeg)

图 22:通过大口连接注入的 JavaScript 部分

如果您熟悉 Visual Studio 和 ASP.NET 网络开发，您可能会遇到类似的情况。在那里，它被称为浏览器链接，在那里您可以在 Visual Studio 中更改 CSS 文件中的某些内容，它会自动更新浏览器。

在这一章中，您看到了 grave . js 不仅擅长运行任务，而且还善于观察变化。以一种聪明的方式开始工作，你可以摆脱必须不断手动执行大口任务的负担，甚至自己重装浏览器。这让你有更多的时间专注于重要的事情:编写解决业务需求的可靠代码。