自动化工具 Gulp
自动化工具 gulp
摘要
概念:gulp用于自动化开发流程。
理解:我们只需要编写任务,然后gulp帮我们执行
核心概念:
任务:通过定义不同的任务来组织你的构建流程。
管道:通过管道方式将文件从一个插件传递到下一个插件,从而进行一系列的处理。
插件:Gulp 社区提供了大量的插件,用于实现各种常见的任务,如文件压缩、CSS 预处理等。
Gulp和Webpack的区别:
gulp的核心理念是task runner:可以定义自己的一系列任务,等待任务被执行。
webpack的核心理念是module bundler:可以使用各种的loader来加载不同的模块,也可以使用各种各样的插件在webpack打包的生命周期完成其他的任务。
概念
**概念:**A toolkit to automate & enhance your workflow
一个工具包,可以帮你自动化和增加你的工作流。
解释:
Gulp 是一个流行的基于 JavaScript 的构建工具,用于自动化开发工作流程。它通过定义任务(tasks)来处理和转换项目中的文件,例如编译 Sass 或 LESS、压缩 JavaScript、优化图像等。Gulp 以其简单易用、插件丰富和速度快等特点受到许多前端开发者的欢迎。

核心概念:
任务(Tasks):
- 在 Gulp 中,任务是执行特定操作的 JavaScript 函数,如编译代码、处理文件等。你可以通过定义不同的任务来组织你的构建流程。
管道(Pipes):
- Gulp 利用 Node.js 的流(stream)机制,通过管道方式将文件从一个插件传递到下一个插件,从而进行一系列的处理。这种流式处理方式使得 Gulp 效率很高,不需要将文件全部加载到内存中。
插件(Plugins):
- Gulp 社区提供了大量的插件,用于实现各种常见的任务,如文件压缩、CSS 预处理、文件合并等。每个插件通常只负责一种功能,这符合了 Unix 哲学“做好一件事”的原则。
Gulp和Webpack:
gulp的核心理念是task runner:可以定义自己的一系列任务,等待任务被执行。
基于文件Stream的构建流,我们可以使用gulp的插件体系来完成某些任务;
webpack的核心理念是module bundler
webpack是一个模块化的打包工具,可以使用各种各样的loader来加载不同的模块。
可以使用各种各样的插件在webpack打包的生命周期完成其他的任务。
gulp相对于webpack的优缺点:
- gulp相对于webpack思想更加的简单、易用,更适合编写一些自动化的任务。
但是目前对于大型项目(Vue、React、Angular)并不会使用gulp来构建,比如默认gulp是不支持模块化的。
基本使用
安装
首先,安装gulp:
# 全局安装
npm install gulp -g# 局部安装
npm install gulp
其次,编写gulpfile.js文件,在其中创建一个任务:
gulpfile.js
const foo = (cb) => {console.log('第一个 gulp 任务')cb()
}module.exports = {foo
}
最后,执行gulp命令:
npx gulp foo
结果:
nathanchen@192 gulp % npx gulp foo
[10:00:14] Using gulpfile ~/Downloads/CoderWhy/17_Webpack工程化高级/code/Nathan/gulp/gulpfile.js
[10:00:14] Starting 'foo'...
第一个 gulp 任务
[10:00:14] Finished 'foo' after 1.25 ms
创建gulp的任务
每个gulp任务都是一个异步的JavaScript函数:
- 此函数可以接受一个callback作为参数,调用callback函数那么任务会结束。
- 或者是一个返回stream、promise、event emitter、child process或observable类型的函数;
任务可以是public或者private类型的:
公开任务(Public tasks):从 gulpfile 中被导出(export),可以通过 gulp 命令直接调用。
私有任务(Private tasks):被设计为在内部使用,通常作为 series() 或 parallel() 组合的组成部分。
补充:gulp4之前, 注册任务时通过gulp.task的方式进行注册的
gulp.task("bar", cb => {console.Log("bar任务");cb();
}
默认任务
我们可以编写一个默认任务:
module.exports.default = (cb) => {console.log('default task exec~')cb()
}
执行 gulp 命令:
nathanchen@192 gulp % npx gulp
[10:08:03] Using gulpfile ~/Downloads/CoderWhy/17_Webpack工程化高级/code/Nathan/gulp/gulpfile.js
[10:08:03] Starting 'default'...
default task exec~
[10:08:03] Finished 'default' after 1.07 ms
gulp的任务组合
任务组合series和parallel:
通常一个函数中能完成的任务是有限的(放到一个函数中也不方便代码的维护),所以我们会将任务进行组合。gulp提供了两个强大的组合方法:
**series():**串行任务组合。 依次执行任务。
**parallel():**并行任务组合。同时执行任务。
Code:
//多个任务串行执行
const seriesTask = series(taskl, task2, task3)
//多个任务并行执行
const parallelTask = parallel(task1, task2, task3)
Case:
const { series, parallel } = require('gulp')const foo1 = (cb) => {setTimeout(() => {console.log('foo1 task exec~')cb()}, 1000)
}const foo2 = (cb) => {setTimeout(() => {console.log('foo1 task exec~')cb()}, 2000)
}const foo3 = (cb) => {setTimeout(() => {console.log('foo1 task exec~')cb()}, 3000)
}const seriesFoo = series(foo1, foo2, foo3)
const parallelFoo = parallel(foo1, foo2, foo3)module.exports = {seriesFoo,parallelFoo
}
gulp的文件操作
读取和写入文件
gulp 暴露了 src() 和 dest() 方法用于处理计算机上存放的文件。
src()
src() 接受参数,并从文件系统中读取文件然后生成一个Node流(Stream),它将所有匹配的文件读取到内存中并通过流 (Stream)进行处理。由 src() 产生的流(stream)应当从任务(task函数)中返回并发出异步完成的信号。
dest()
dest() 接受一个输出目录作为参数,并且它还会产生一个 Node流(stream),通过该流将内容输出到文件中。
pipe()
流(stream)所提供的主要的 API 是 .pipe() 方法,pipe方法的原理是什么呢?
pipe方法接受一个 转换流(Transform streams)或 可写流(Writable streams)。
转换流或者可写流,在拿到数据后可以对数据进行处理,再次传递给下一个转换流或者可写流。
gulpfile.js
const { src, dest } = require('gulp')
const copyFile = () => {// 读取文件,写入文件// gulp 需要回调函数,而 pipe 返回的是一个 stream,所以这里直接return即可return src("./src/main.js").pipe(dest("./dist"))
}module.exports = {copyFile
}
res:
nathanchen@192 gulp % npx gulp copyFile
[10:33:57] Using gulpfile ~/Downloads/gulp/gulpfile.js
[10:33:57] Starting 'copyFile'...
[10:33:57] Finished 'copyFile' after 14 ms
glob文件匹配
src() 方法接受一个 glob 字符串或由多个 glob 字符串组成的数组作为参数,用于确定哪些文件需要被操作。glob 或 glob 数组必须至少匹配到一个匹配项,否则 src() 将报错。
glob的匹配规则如下:
-
(一个星号*):在一个字符串中,匹配任意数量的字符,包括零个匹配;
比如
'*.js' -
(两个星号**):在多个字符串匹配中匹配任意数量的字符串,通常用在匹配目录下的文件;
比如
'scripts/**/*.js',**表示匹配任意多个字符串,可以匹配/scirpts/a/b/c.js -
(取反!):
由于 glob 匹配时是按照每个 glob 在数组中的位置依次进行匹配操作的。
所以 glob 数组中的取反(negative)glob 必须跟在一个非取反(non-negative)的 glob 后面。
第一个 glob 匹配到一组匹配项,然后后面的取反 glob 删除这些匹配项中的一部分。
['script/**/*.js', '!scripts/vendor/']
对文件进行转换
**需求:**如果在这个过程中,我们希望对文件进行某些处理,可以使用社区给我们提供的插件。
比如我们希望ES6转换成ES5,那么可以使用babel插件。
如果我们希望对代码进行压缩和丑化,那么可以使用uglify或者terser插件。
Case: babel 转换
pnpm add @babel/core gulp-babel @babel/preset-env -D
gulpfile.js
const { src, dest } = require('gulp')
const babel = require('gulp-babel')const copyFile = () => {// 读取文件,写入文件// gulp 需要回调函数,而 pipe 返回的是一个 stream,所以这里直接return即可return src("./src/**/*.js").pipe(babel({ presets: ["@babel/preset-env"] })).pipe(dest("./dist"))
}module.exports = {copyFile
}
结果:
转换前 main.js
const test = () => {console.log('test')
}test()
转换后main.js
"use strict";var test = function test() {console.log('test');
};
test();
Gulp的文件监听
watch
gulp api 中的 watch() 方法利用文件系统的监控程序(file system watcher)将 与进行关联。
Case: 监听内容的变化
gulpfile.js
const { src, dest, watch } = require('gulp')
const babel = require('gulp-babel')const copyFile = () => {return src("./src/**/*.js").pipe(babel({ presets: ["@babel/preset-env"] })).pipe(dest("./dist"))
}watch("./src/**/*.js", copyFile) // 监听module.exports = {copyFile
}
res: 修改 main.js ,会自动执行 copyFile
nathanchen@192 gulp % npx gulp copyFile
[11:04:12] Using gulpfile ~/Downloads/CoderWhy/17_Webpack工程化高级/code/Nathan/gulp/gulpfile.js
[11:04:12] Starting 'copyFile'...
[11:04:12] Finished 'copyFile' after 415 ms
[11:04:28] Starting 'copyFile'...
[11:04:28] Finished 'copyFile' after 23 ms
gulp 案例
**需求:**通过gulp来开启本地服务和打包。
打包html文件
**打包html文件:**使用gulp-htmlmin插件。
pnpm add gulp-htmlmin -D
gulpfile.js
const { src, dest, watch } = require('gulp')
const htmlmin = require('gulp-htmlmin')const htmlTask = () => {// 读取文件,写入文件// gulp 需要回调函数,而 pipe 返回的是一个 stream,所以这里直接return即可return src("./src/**/*.html").pipe(htmlmin({ collapseWhitespace: true })).pipe(dest("./dist"))
}watch("./src/**/*.html", htmlTask)module.exports = {htmlTask
}
执行命令:
nathanchen@192 gulp % npx gulp htmlTask
[13:26:01] Using gulpfile ~/Downloads/CoderWhy/17_Webpack工程化高级/code/Nathan/gulp/gulpfile.js
[13:26:01] Starting 'htmlTask'...
[13:26:01] Finished 'htmlTask' after 17 ms
产物如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>Document</title></head><body><h1>Gulp</h1></body>
</html>
打包JavaScript文件
**打包JavaScript文件:**使用gulp-babel,gulp-terser插件。
安装插件:
pnpm add @babel/core gulp-babel @babel/preset-env -D
pnpm add gulp-terser -D
gulpfile.js
const babel = require('gulp-babel')
const terser = require('gulp-terser')const jsTask = () => {return src("./src/**/*.js").pipe(babel({ presets: ["@babel/preset-env"] })).pipe(terser({ toplevel: true })).pipe(dest('./dist'))
}module.exports = {jsTask
}
打包less文件
**打包less文件:**使用gulp-less插件
nathanchen@192 gulp % pnpm add gulp-less -D
gulpfile.js
const less = require('gulp-less')const lessTask = () => {return src("./src/**/*.less").pipe(less()).pipe(dest('./dist'))
}module.exports = {lessTask
}
html资源注入
- 使用gulp-inject插件:将js和less注入到html文件中
pnpm add gulp-inject -D
- 使用browser-sync插件:文件更新,浏览器同步更新
pnpm add browser-sync -D
操作:
执行 npm run build 进行打包,npm run serve开启服务器。
gulpfile.js
const { src, dest, watch, parallel, series } = require('gulp')
const htmlmin = require('gulp-htmlmin')
const babel = require('gulp-babel')
const terser = require('gulp-terser')
const less = require('gulp-less')
const inject = require('gulp-inject')
const browserSync = require('browser-sync')// 打包html
const htmlTask = () => {// 读取文件,写入文件// gulp 需要回调函数,而 pipe 返回的是一个 stream,所以这里直接return即可return src('./src/**/*.html').pipe(htmlmin({ collapseWhitespace: true })).pipe(dest('./dist'))
}// 打包js
const jsTask = () => {return src('./src/**/*.js').pipe(babel({ presets: ['@babel/preset-env'] })).pipe(terser({ toplevel: true })).pipe(dest('./dist'))
}// 打包less
const lessTask = () => {return src('./src/**/*.less').pipe(less()).pipe(dest('./dist'))
}// 在html中注入js和css
const injectTask = () => {return src('./dist/**/*.html').pipe(inject(src(['./dist/**/*.css', './dist/**/*.js']), { relative: true })).pipe(dest('./dist'))
}// 开启本地服务
const bs = browserSync.create()
const serve = () => {// 进行监听watch('./src/**', buildTask)bs.init({port: 8080,open: true,files: './dist/*',server: {baseDir: './dist'}})
}// 创建项目构建的任务
const buildTask = series(parallel(htmlTask, jsTask, lessTask), injectTask)
const serveTask = series(buildTask, serve)module.exports = {buildTask,serveTask
}
package.json
{..."scripts": {"build": "gulp buildTask","serve": "gulp serveTask"},...
}
相关文章:
自动化工具 Gulp
自动化工具 gulp 摘要 概念:gulp用于自动化开发流程。 理解:我们只需要编写任务,然后gulp帮我们执行 核心概念: 任务:通过定义不同的任务来组织你的构建流程。 管道:通过管道方式将文件从一个插件传递…...
css实现div被图片撑开
固定好盒子的宽度,高度随传过来的图片大小决定 <div class"tab-con"> <img:src"concertInfo.detail"alt""> </div>.tab-con {margin-bottom: 20px;width: 700px;img {width: 700px;height: auto;object-fit: cont…...
Power Pivot、Power BI 和 SQL Server Analysis Services 的公式语言:DAX(数据分析表达式)
DAX(Data Analysis Expressions)是一种用于 Power Pivot、Power BI 和 SQL Server Analysis Services 的公式语言,旨在帮助用户进行数据建模和复杂计算。DAX 的设计初衷是使数据分析变得简单而高效,特别是在处理数据模型中的表关系…...
大模型应用编排工具Dify二开之工具和模型页面改造
1.前言 简要介绍下 dify: 一款可以对接市面上主流大模型的任务编排工具,可以通过拖拽形式进行编排形成解决某些业务场景的大模型应用。 背景信息: 环境:dify-0.8.3、docker-21 最近笔者在做 dify的私有化部署和二次…...
Pytorch用BERT对CoLA、新闻组文本数据集自然语言处理NLP:主题分类建模微调可视化分析...
原文链接:https://tecdat.cn/?p38181 自然语言处理(NLP)领域在近年来发展迅猛,尤其是预训练模型的出现带来了重大变革。其中,BERT 模型凭借其卓越性能备受瞩目。然而,对于许多研究者而言,如何高…...
LightGBM-GPU不能装在WSL,能装在windows上
这是一篇经验总结文章,注重思路,忽略细节。 1.起因 用多个机器学习方法训练模型,比较性能,发现Light GBM方法获得的性能明显更高,但问题是在CPU上训练的速度特别特别慢,需要用GPU训练。 2.开始装LightGB…...
工业相机常用功能之白平衡及C++代码分享
目录 1、白平衡的概念解析 2、相机白平衡参数及操作 2.1 相机白平衡参数 2.2 自动白平衡操作 2.3 手动白平衡操作流程 3、C++ 代码从XML读取参数及设置相机参数 3.1 读取XML 3.2 C++代码,从XML读取参数 3.3 给相机设置参数 1、白平衡的概念解析 白平衡(White Balance)…...
Foundry 单元测试
安装 Foundry 如果你还没有安装 Foundry,请按照此处的说明进行操作:Foundry 安装 Foundry Hello World 只需运行以下命令,它将为你设置环境,创建测试并运行它们。(当然,这假设你已经安装了 Foundry&…...
idea database连接数据库后看不到表解决方法、格式化sql快捷键
最下面那个勾选上就可以了 或 格式化sql快捷键: 先选中, 使用快捷键格式化 SQL: Windows/Linux: Ctrl Alt L macOS: Cmd Alt L...
【数学二】线性代数-向量-向量组的秩、矩阵得秩
考试要求 1、理解 n n n维向量、向量的线性组合与线性表示的概念. 2、理解向量组线性相关、线性无关的概念,掌握向量组线性相关、线性无关的有关性质及判别法. 3、了解向量组的极大线性无关组和向量组的秩的概念,会求向量组的极大线性无关组及秩. 4、了解向量组等价的概念,…...
ABAP开发-内存管理
系列文章目录 文章目录 系列文章目录前言一、概述二、程序间调用三、外部会话和内部会话四、SAP内存与ABAP内存五、实例总结 前言 一、概述 内存是程序之间为了传递数据而使用的共享存储空间,在每个程序里使用的内存有SAP内存和ABAP内存 SAP内存分类 SAP内存 主会…...
【Ajax】跨域
文章目录 1 同源策略1.1 index.html1.2 server.js 2 如何解决跨域2.1 JSONP2.1.1 JSONP 原理2.1.2 JSONP 实践2.1.3 jQuery 中的 JSONP 2.2 CORS2.2.1 CORS实践 3 server.js 1 同源策略 同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策…...
yii 常用一些调用
yii 常用一些调用 (增加中) 调用YII框架中 jquery:Yii::app()->clientScript->registerCoreScript(‘jquery’); framework/web/js/source的js,其中registerCoreScript key调用的文件在framework/web/js/packages.php列表中可以查看 在view中得到当前contro…...
网页版五子棋——用户模块(服务器开发)
前一篇文章:网页版五子棋—— WebSocket 协议-CSDN博客 目录 前言 一、编写数据库代码 1.数据库设计 2.配置 MyBatis 3.创建实体类 4.创建 UserMapper 二、前后端交互接口 1.登录接口 2.注册接口 3.获取用户信息 三、服务器开发 1.代码编写 2.测试后端…...
以RK3568为例,ARM核心板如何实现NTP精准时间同步?
背景 网络时间协议NTP(Network TimeProtocol)是用于互联网中时间同步的标准互联网协议,可以把计算机的时间同步到某些时间标准。NTP对于我们产品来说有什么用呢,简单的讲,当你的设备时间不准确了,你可以接…...
Twitter(X)2024最新注册教程
Twitter 现名为X,因为图标是一只小鸟的形象,大家也叫它小蓝鸟(埃隆马斯克于 2023 年对该平台进行了品牌重塑),目前仍然是全球最受欢迎的社交媒体和微博平台之一,全球活跃用户量大概在4.5亿。尤其是欧美国家…...
10.桥接模式设计思想
10.桥接模式设计思想 目录介绍 01.桥接模式基础 1.1 桥接模式由来1.2 桥接模式定义1.3 桥接模式场景1.4 桥接模式思考1.5 解决的问题 02.桥接模式实现 2.1 罗列一个场景2.2 桥接结构2.3 桥接基本实现2.4 有哪些注意点 03.桥接实例演示 3.1 需求分析3.2 代码案例实现3.3 是否可…...
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
这里是Themberfue 在上一节的最后,我们讨论两个线程同时对一个变量累加所产生的现象 在这一节中,我们将更加详细地解释这个现象背后发生的原因以及该如何解决这样类似的现象 线程安全问题 public class Demo15 {private static int count 0;public …...
(已解决)Dependency “ ” not found 细谈
剖析原因:依赖在pom文件中引用后,然后ReLoad,此依赖会在你配置的本地仓库里面找,并下载下来,他报not found就是没有找到。 本地仓库的位置: 进一步深究:在本地仓库找的时候,他又会…...
网络编程、UDP、TCP、三次握手、四次挥手
一、初识网络编程 网络编程的概念:在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件等等。 不管是什么场景,都是计算机和计算机之间通过网络进行…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
