自动化工具 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、三次握手、四次挥手
一、初识网络编程 网络编程的概念:在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件等等。 不管是什么场景,都是计算机和计算机之间通过网络进行…...

程序员的生活周刊 #7:耐克总裁被裁记
0. 庙宇 这张图来自 Tianshu Liu, 被树木环绕的宝塔庙宇 1. 耐克总裁 耐克最近的总裁 John Donahoe 干了 5 年,终于被裁掉了。 这位总裁即不了解球鞋文化,也没有零售经验,但不懂事的董事会还是聘用它,寄托把耐克从运…...

sparkSQL的UDF,最常用的regeister方式自定义函数和udf注册方式定义UDF函数 (详细讲解)
- UDF:一对一的函数【User Defined Functions】 - substr、split、concat、instr、length、from_unixtime - UDAF:多对一的函数【User Defined Aggregation Functions】 聚合函数 - count、sum、max、min、avg、collect_set/list - UDTF:…...

【Ubuntu20】VSCode Python代码规范工具配置 Pylint + Black + MyPy + isort
常用工具: 在 Ubuntu20 下,有以下常见的 Python 代码工具: 静态分析工具: Pylint 和 Flake8 功能范围:Pylint功能非常强大,能够检查代码质量、潜在错误、代码风格、复杂度等多个方面, 并生成详细的报…...

游戏提示错误:xinput1_3.dll缺失?四种修复错误的xinput1_3.dll文件
在计算机的运行过程中,我们可能会遇到各种各样的问题,其中与“xinput1_3.dll”相关的问题也并不罕见。“xinput1_3.dll”是一个在许多游戏和多媒体应用程序运行过程中可能会用到的动态链接库文件。当我们启动某些游戏时,可能会突然弹出一个错…...

YOLOv11融合IncepitonNeXt[CVPR2024]及相关改进思路
YOLOv11v10v8使用教程: YOLOv11入门到入土使用教程 一、 模块介绍 论文链接:https://arxiv.org/abs/2303.16900 代码链接:https://github.com/sail-sg/inceptionnext 论文速览:受 ViT 长距离建模能力的启发,大核卷积…...

[Web安全 网络安全]-学习文章汇总导航(持续更新中)
文章目录: 一:学习路线资源 1.路线 2.资源 二:工具 三:学习笔记 1.基础阶段 2.进阶阶段 四:好的参考 五:靶场 博主对网络安全很感兴趣,但是不知道如何取学习,自己一步一步…...

Docker Compose部署Rabbitmq(Docker file安装延迟队列)
整个工具的代码都在Gitee或者Github地址内 gitee:solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb github:GitHub - ZeroNing/solomon-parent: 这个项目主要是…...

SpringBoot+FileBeat+ELK8.x版本收集日志
一、准备环境 1、ElasticSearch:8.1.0 2、FileBeat:8.1.0 3、Kibana:8.1.0 4、logstach:8.1.0 本次统一版本:8.1.0,4个组件,划分目录,保持版本一致。 说明:elasticsearch和kib…...

本地模型导入ollama
文章目录 Modelfile模板导入到 ollama Modelfile模板 在本地模型目录下创建 Modelfile FROM ./qwen2.5-7b-instruct-q4_k_m.gguf# 设定温度参数为1 [更高的更具有创新性,更低的更富有连贯性] PARAMETER temperature 1 # 将上下文窗口大小设置为4096,这…...

scala Map训练
Map实训内容: 1.创建一个可变Map,用于存储图书馆中的书籍信息(键为书籍编号,值为包含书籍名称、作者、库存数量的元组),初始化为包含几本你喜欢的书籍信息。 2.使用 操作符添加两本新的书籍到图书馆集合中。 3.根据书籍编号查询某一本特定的书籍信息&…...