Gulp学习(1)创建任务、异步执行、处理文件、Glob详解

本文详细介绍Gulp的安装、配置及使用方法,涵盖任务定义、异步处理、文件处理、组合任务等核心功能,助您快速掌握Gulp自动化构建流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ulp学习:

gulp的安装
1、检查node、npm是否正确安装
在终端中输入:
node -v
npm -v
看是否会回复版本号
这里我推荐使用nvm,它可以帮你一次性下载完node和它所对应的npm版本

2、安装gulp
(1)npm init:
在项目本地自动创建一个package.json文件,里面会写入项目所有的依赖,
以后别人再用你的项目进行编写时,可以用npm imstall读取package.json
中的依赖,自动下载

(2) 先全局安装: npm install gulp -g
再项目本地安装: npm install gulp --save-dev
–save-dev 下载时会自动将依赖文件写入package.json

3、创建环境
在项目的目录下创建一个gulpfile.js文件,用来编写gulp代码(允许首字母大写,Gulpfile.js)

gulp的转译:
可以通过修改 gulpfile.js 文件的扩展名来表明所用的编程语言并安装对应的转译模块

例如:
对于 TypeScript,重命名为 gulpfile.ts 并安装 ts-node 模块
对于 Babel,重命名为 gulpfile.babel.js 并安装 @babel/register 模块

创建任务(task):
每个gulp任务(task)都是一个异步的 JavaScript 函数,
此函数是一个可以接收 callback 作为参数的函数,
或者是一个返回 stream、promise、event emitter、child process或observable类型值的函数。

任务(tasks)可以是 public(公开)或 private(私有)类型的:
1、公开任务(Public tasks)
从 gulpfile中被导出(export),可以通过gulp命令直接调用
例如:
gulp.task(‘css’, function(){

})

gulp css

2、私有任务(Private tasks)被设计为在内部使用,通常作为series()(串行)或parallel()(并行)组合的组成部分

在以前的gulp版本中,task()方法用来将函数注册为任务(task)
虽然这个API依旧是可以使用的,但是导出(export)将会是主要的注册机制
除非遇到 export 不起作用的情况。

var gulp = require(‘gulp’)

gulp.task(“build”, function(){
console.log(‘hello world’);
})

gulp build

Using gulpfile E:\gulpLearnExample\gulpfile.js
Starting ‘build’…
hello world
The following tasks did not complete: build
Did you forget to signal async completion?

这里说的时bulid函数没有完成。指的是我们上面的函数未指定返回值当需要使用 callback 或返回 stream、promise、event emitter、child process、observable 来解决此问题。

我们把上述代码改写为异步加载的格式:

			var gulp = require('gulp')

			gulp.task("build", async function(){
				await console.log('hello world');
			})

			>gulp build

			Using gulpfile E:\gulpLearnExample\gulpfile.js
			Starting 'build'...
			hello world
			Finished 'build' after 3.4 ms

完美,不是吗0.0!

我们也可以把任务公有导出:

		const { series } = require('gulp');

		var build = async function(){
			await console.log('hello world');
		}

		exports.build = build; 

		>gulp --tasks
		查看gulpfile.js文件中的任务
		>gulo build
		运行gulpfile.js文件中的任务

组合任务
Gulp 提供了两个强大的组合方法:series()和parallel()
允许将多个独立的任务组合为一个更大的操作
这两个方法都可以接受任意数目的任务(task)函数或已经组合的操作
series() 和 parallel() 可以互相嵌套至任意深度
1、如果需要让任务(task)按顺序执行,请使用series()方法
2、对于希望以最大并发来运行的任务(tasks),可以使用parallel()方法将它们组合起来

任务(task)完成通知:
当从任务(task)中返回 stream、promise、event emitter、child process或observable 时,
成功或错误值将通知 gulp 是否继续执行或结束
如果任务(task)出错,gulp 将立即结束执行并显示该错误

当使用 series() 组合多个任务(task)时,
任何一个任务(task)的错误将导致整个任务组合结束,并且不会进一步执行其他任务
当使用 parallel() 组合多个任务(task)时,
一个任务的错误将结束整个任务组合的结束,但是其他并行的任务(task)可能会执行完,也可能没有执行完

使用 async/await
如果不使用前面提供到几种方式,你还可以将任务(task)定义为一个async(异步)函数,
它将利用promise对你的任务(task)进行包装。这将允许你使用await处理 promise

处理文件:
gulp给出了src()和dest()方法用于处理计算机上存放的文件

1、src()接受一个glob参数,并从文件系统中读取文件然后生成一个Node流(stream)文件
它将所有匹配的文件读取到内存中并通过流(stream)进行处理

由 src()产生的流(stream)应当从任务(task)中返回并发出异步完成的信号

2、流(stream)所提供的主要的API是.pipe()方法
用于连接转换流(Transform streams)或可写流(Writable streams)

3、dest()接受一个输出目录作为参数,并且它还会产生一个Node流(stream),通常作为终止流(terminator stream)
当它接收到通过管道(pipeline)传输的文件时,它会将文件内容及文件属性写入到指定的目录中

gulp 还提供了 symlink() 方法,其操作方式类似 dest(),但是创建的是链接而不是文件

大多数情况下,利用 .pipe() 方法将插件放置在 src() 和 dest() 之间,并转换流(stream)中的文件

		例如:
			var gulp = require('gulp');
			var cssnano = require('gulp-cssnano');

			gulp.task('css',async function(){
				await gulp.src("./src/css/*.css")
				.pipe(cssnano())
				.pipe(gulp.dest('./dist/css/'));
			})

向流(stream)中添加文件
src()也可以放在管道(pipeline)的中间,以根据给定的 glob 向流(stream)中添加文件
新加入的文件只对后续的转换可用
如果glob匹配的文件与之前的有重复,仍然会再次添加文件。

		例如:
			var gulp = require('gulp');
			var cssnano = require('gulp-cssnano');

			gulp.task('css',async function(){
				await gulp.src("./src/css/*.css")
				.pipe(cssnano())
				.pipe(gulp.src("./src/scss/*.css"))
				.pipe(cssnano())
				.pipe(gulp.dest('./dist/css/'));
			})

分阶段输出
dest()可以用在管道(pipeline)中间用于将文件的中间状态写入文件系统
当接收到一个文件时,当前状态的文件将被写入文件系统,文件路径也将被修改以反映输出文件的新位置,然后该文件继续沿着管道(pipeline)传输

此功能可用于在同一个管道(pipeline)中创建未压缩(unminified)和已压缩(minified)文件

流(stream)模式:
流动(streaming)、缓冲(buffered)和空(empty)模式

src()可以工作在三种模式下:
缓冲(buffering)、流动(streaming)和空(empty)模式
这些模式可以通过对src()的buffer和read参数进行设置

缓冲(Buffering)模式是默认模式
将文件内容加载内存中
插件通常运行在缓冲(buffering)模式下

流动(Streaming)模式的存在主要用于操作无法放入内存中的大文件
例如巨幅图像或电影
文件内容从文件系统中以小块的方式流式传输,而不是一次性全部加载

空(Empty)模式不包含任何内容,仅在处理文件元数据时有用

Glob详解
1、glob是由普通字符和/或通配字符(*)组成的字符串,用于匹配文件路径
可以利用一个或多个 glob 在文件系统中定位文件

src()方法接受一个glob字符串或由多个glob字符串组成的数组作为参数,用于确定哪些文件需要被操作
glob 或 glob 数组必须至少匹配到一个匹配项,否则src()将报错
当使用glob数组时,将按照每个glob在数组中的位置依次执行匹配-这尤其对于取反(negative)glob 有用

	例如:
		var gulp = require('gulp');
		var cssnano = require('gulp-cssnano');

		gulp.task('css',async function(){
			await gulp.src(["./src/css/*.css","./src/scss/*.css"])
			.pipe(cssnano())
			.pipe(gulp.dest('./dist/css/'));
		})

2、字符串片段、分隔符与特殊字符
字符串片段(segment)是指两个分隔符之间的所有字符组成的字符串
在glob中,分隔符永远是/字符(不区分操作系统)
在glob中\字符被保留作为转义符使用。
如下所示,*被转义了,因此,将被作为一个普通字符使用,而不再是通配符了
'glob_with_uncommon_\
_character.js’

注意:
避免使用Node的path类方法来创建glob,例如path.join

在Windows中,由于Node使用\作为路径分隔符,因此将会产生一个无效的glob
还要避免使用__dirname和 __filename全局变量
同样的,process.cwd()方法也要避免使用

		例如:
			const invalidGlob = path.join(__dirname, 'src/*.js');

特殊字符:*(一个星号):
在一个字符串片段中匹配任意数量的字符,包括零个匹配
对于匹配单级目录下的文件很有用

特殊字符:**(两个星号)
在多个字符串片段中匹配任意数量的字符,包括零个匹配
对于匹配嵌套目录下的文件很有用

注意:
请确保适当地限制带有两个星号的glob的使用,以避免匹配大量不必要的目录

特殊字符:!(取反)
由于glob匹配时是按照每个glob在数组中的位置依次进行匹配操作的,所以 glob 数组中的取反(negative)glob必须跟在一个非取反(non-negative)的glob后面

第一个 glob 匹配到一组匹配项,然后后面的取反 glob 删除这些匹配项中的一部分
如果取反glob只是由普通字符组成的字符串,则执行效率是最高的

匹配重叠(Overlapping globs)
两个或多个 glob 故意或无意匹配了相同的文件就被认为是匹配重叠(overlappin)了
如果在同一个src()中使用了会产生匹配重叠的globg,ulp将尽力去除重叠部分,

但是在多个src()调用时产生的匹配重叠是不会被去重的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值