前端工程化 02 - Gulp入门

前端工程化 02 - Gulp入门

Gulp其实就是一个实现自动监听文件变化,调用插件来进行编译各种工程文件的工具。本质上和webpack是一样的。只不过配置的内容更加详细。 Gulp主要是通过安装插件,然后在gulp的任务文件里定义好需要监听的文件内容,然后调用插件进行预处理,最后在指定的位置生成最终工程文件。 Udemy的课程没有

Gulp其实就是一个实现自动监听文件变化,调用插件来进行编译各种工程文件的工具。本质上和webpack是一样的。只不过配置的内容更加详细。 Gulp主要是通过安装插件,然后在gulp的任务文件里定义好需要监听的文件内容,然后调用插件进行预处理,最后在指定的位置生成最终工程文件。 Udemy的课程没有Webpack,先把Gulp了解一下,之后再搞Webpack,毕竟在Webstorm里启动Vue项目,默认模板就是Webpack。
  1. Gulp安装
  2. 配置Gulp任务
  3. 自动侦听任务
  4. 配置CSS工程环境

Gulp

安装好了Node.js+NPM之后,需要安装Gulp。Gulp的安装方式有两种:全局安装和局部安装。 在开发一个项目的时候,需要同时进行全局安装和局部安装。

全局安装Gulp

所谓全局安装,就是在命令行里直接打Gulp有没有反应,有就是全局安装,如果需要在项目中运行,就是局部安装。 Gulp是开发工具,开发工具一般都全局安装比较方便,因为要执行命令行模式,所以必须要全局安装。 通过npm全局安装Gulp的命令是:
npm install gulp-cli --global
之后会看到提示,安装成功:
+ gulp-cli@2.2.0
added 236 packages from 157 contributors in 37.959s
然后随便创建一个项目,到项目目录中路径,在命令行模式下运行:
>gulp -v
CLI version: 2.2.0
Local version: Unknown

>gulp
[09:18:41] Local modules not found in D:\Coding\frontendworkflow
[09:18:41] Try running: npm install
能够正确显示版本号,有报错信息是因为还没有配置gulp的任务,但是说明gulp已经在全局环境下生效了。

局部安装

如果项目需要协同工作,但其他计算机上没有安装全局环境的Gulp,这个时候可以将Gulp作为项目包的一部分进行安装,由于Gulp是开发工具,并不是我们项目运行时的依赖,所以安装的时候和安装普通的包略有不同:
npm install gulp --save-dev
这会把Gulp放入当前项目目录的包目录中,Udemy的视频里是在package.json中增加了一个新的依赖devDependencies项目,而我实际执行,是新生成了一个package-lock.json文件。 查了一下发现这个是新版npm用来版本锁定的文件,只要存在这个文件,会优先按照这个文件中安装依赖。用了也没什么问题,这个文件也需要一并提交到git上,这样才能保证版本一致。 同时package.json中也更新了gulp的依赖:
{
  "name": "frontendworkflow",
  "version": "1.0.0",
  "devDependencies": {
    "gulp": "^4.0.2"
  }
}
这样就完成了Gulp的安装。

配置Gulp任务

Gulp的核心功能是当项目中的文件发生变化的时候,进行一些任务。Gulp相关的任务,需要写在项目根目录下边的gulpfile.js文件中。 项目根目录下创建一个gulpfile.js文件,来简单入门一下任务编写:
var gulp = require('gulp');

gulp.task("default", function () {
    console.log("My first gulp task");
});
这段代码先导入Gulp库,然后使用gulp.task()启动一个任务,第一个参数是任务名称,在命令行中启动具体任务的时候需要任务名,第二个参数是实际要执行的工作。这里的名称default是一个特殊的名称,表示默认任务。 然后在项目根目录运行命令:
>gulp default
[09:53:00] Using gulpfile D:\Coding\frontendworkflow\gulpfile.js
[09:53:00] Starting 'default'...
My first gulp task
[09:53:00] The following tasks did not complete: default
[09:53:00] Did you forget to signal async completion?
代码执行了,但是提示没有返回异步完成的通知,这里查了一下,官方文档里说需要使用一个特别的done参数,通知任务完成,代码需要改成这样:
var gulp = require('gulp');

gulp.task("default", done=> {
    console.log("My first gulp task");
    done();
});
再执行,就能顺利完成任务了:
>gulp
[09:54:53] Using gulpfile D:\Coding\frontendworkflow\gulpfile.js
[09:54:53] Starting 'default'...
My first gulp task
[09:54:53] Finished 'default' after 3.96 ms
可见执行了gulp之后,就会在当前目录下寻找gulpfile.js文件,然后按照任务名称执行对应的任务。 再添加几个其他的任务试验一下:
var gulp = require('gulp');

gulp.task("default", done=> {
    console.log("My first gulp task");
    done();
});

gulp.task('html',done=>{
    console.log("Processing HTML file...");
    done();
});

gulp.task('css',done=>{
    console.log("Processing CSS file ...");
    done();
});
之后可以使用gulp taksname的方式启动任务:
>gulp html
[09:56:55] Using gulpfile D:\Coding\frontendworkflow\gulpfile.js
[09:56:55] Starting 'html'...
Processing HTML file...
[09:56:55] Finished 'html' after 3.57 ms

>gulp css
[09:56:59] Using gulpfile D:\Coding\frontendworkflow\gulpfile.js
[09:56:59] Starting 'css'...
Processing CSS file ...
[09:56:59] Finished 'css' after 3.75 ms

自动侦听任务

了解了任务之后,需要引入一个插件gulp-watch,使用Gulp进行前端工程化的核心就在于这个插件。 此插件的作用是自动监听文件的变化,一旦产生变化,就执行指定的任务。 先安装该插件:
npm install gulp-watch --save-dev
成功之后,修改gulpfile.js,需要使用这个新包:
var watch = require('gulp-watch');

gulp.task('watchhtml', function (done) {
    watch('./index.html', function () {
        console.log("HTML has changed!!!");
    });
    done();
});
这里注册了一个叫做watchhtml的任务,每次执行的时候,其代码里调用了新的库watch,其第一个参数是要监听的文件路径,可以使用通配符。第二个参数是要执行的任务。 现在用文本编辑器打开项目根目录下的index.html,进行修改然后保存,就会自动触发这个任务,就完成了监听工作。

配置CSS工程环境

现代CSS开发

现代前端协同开发CSS,已经不是直接编写CSS文件了,而是采取以下几种方式:
  1. 将大的CSS文件分割成很多针对具体样式的小文件
  2. CSS文件使用变量来标识色彩等内容,只要修改变量,就可以很容易的修改很多引用CSS变量的实际值
  3. 嵌套编写CSS
CSS的工程文件直接交给浏览器是无法被浏览器解析的,必须通过一系列工具,将CSS工程文件编译成最终生成的标准格式CSS文件。 这个过程和上边的自动侦听任务结合起来,就很方便。只要自动监听CSS文件的变化,然后调用一些预处理库,之后指定生成具体css文件的路径,就可以了。 CSS预处理主要做的事情有:
  1. 自动添加浏览器前缀
  2. 处理CSS变量
  3. 还原CSS嵌套为标准格式
SASS和LASS等都是现代CSS工程预处理的工具。这里我们来使用一些Gulp的插件完成这些工作:

Gulp的流

在开始处理之前,需要知道Gulp的流。还好在之前Spring 5里硬啃了WebFlux,Gulp的流很相似。 gulp.src()用来表示流的起点,也就是源数据。 gulp.pipe()表示流处理过程上的一个节点,其中的参数可以传入处理流的库,处理之后会流向下一个节点 gulp.dest()表示流的目标,注意是一个文件夹的名称,而不是文件名,会自动将编译后的CSS文件放入这个目录中。这个dest本身可以作为一个节点参数放入到gulp.pipe()中。 来看一个不经过任何处理,直接复制css文件的例子:
gulp.task('watchcss', done => {
    console.log("CSS processing...");
    watch('./dev/style/style.css', function () {
        gulp.src('./dev/style/style.css')
            .pipe(gulp.dest('./style'));
    });
    done();
});
这里开发CSS的目录位于项目目录/dev/style/style.css,最终供页面使用的目录在项目的/style目录下,这个任务就是监听style.css的变动,然后将这个文件复制到/style目录下。 编辑一下开发的css文件,做一些修改然后保存,可以看到自动触发了任务:
[10:47:37] Using gulpfile D:\Coding\frontendworkflow\gulpfile.js
[10:47:37] Starting 'watchcss'...
CSS processing...
[10:47:37] Finished 'watchcss' after 17 ms

CSS处理工具

使用的CSS处理工具有:
  1. gulp-postcss,相当于一个壳,调用其他插件处理CSS文件
  2. autoprefixer,自动添加不同浏览器的前缀支持
  3. postcss-simple-vars,用于处理CSS变量
  4. postcss-nested,处理嵌套CSS编译
使用npm --save-dev安装上边的库,然后修改gulpfile.js,向流中添加CSS处理器。
var gulp = require('gulp');
var watch = require('gulp-watch');
var postcss = require("gulp-postcss");
var autoprefixer = require("autoprefixer");
var cssvars = require('postcss-simple-vars');
var nestedcss = require('postcss-nested');

gulp.task('watchcss', done => {
    console.log("CSS processing...");
    watch('./dev/style/style.css', function () {
        gulp.src('./dev/style/style.css')
            .pipe(postcss([cssvars, autoprefixer, nestedcss]))
            .pipe(gulp.dest('./style'));
    });
    done();
});
重新启动新的watchcss任务。然后在style.css中写带有变量,嵌套,有前缀兼容性的css语句来看看:
$mainColor: #2f5572;

body {
    color: $mainColor;
    padding: 25px;
    margin: 10px;
    columns: 300px 2;
}

.box {
    a {
        display: block;
        padding: 10px;
    }

    b {
        display: inline-block;
        padding: 20px;
    }
}
保存之后,在项目的style目录下可以找到编译后的CSS文件,内容如下:
body {
    color: #2f5572;
    padding: 25px;
    margin: 10px;
    -webkit-columns: 300px 2;
       -moz-columns: 300px 2;
            columns: 300px 2;
}

.box a {
    display: block;
    padding: 10px;
}

.box b {
    display: inline-block;
    padding: 20px;
}
现在就初步搭建好了CSS的工程环境。
LICENSED UNDER CC BY-NC-SA 4.0
Comment