项目源码地址

前期准备工作

安装 gulp 命令行工具

npm install --global gulp-cli

在项目目录下创建 package.json 文件

npm init -y

安装 gulp,作为开发时依赖项

npm install --save-dev gulp

检查 gulp 版本

gulp --version
PS D:\a-个人项目管理\使用Gulp搭建项目\gulp-building> gulp --version
CLI version: 2.3.0
Local version: 4.0.2

创建配置文件

在根目录下新建 src 文件夹和 gulpfile.js 文件

src 目录下新建如下文件,其中 index.html 作为我们的入口页面

gulp 中常用方法解释

src

创建一个流,用于从文件系统读取 Vinyl 对象。

函数原型

src(globs, [options])

返回值

返回一个可以在管道的开始或中间使用的流,用于根据给定的 globs 添加文件。

globs

glob 是由普通字符和/或通配字符组成的字符串,用于匹配文件路径。可以利用一个或多个 glob 在文件系统中定位文件。

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

特殊字符: * (一个星号)

在一个字符串片段中匹配任意数量的字符,包括零个匹配。对于匹配单级目录下的文件很有用。

下面这个 glob 能够匹配类似 index.js 的文件,但是不能匹配类似 scripts/index.jsscripts/nested/index.js 的文件。

'*.js'

特殊字符: ** (两个星号)

在多个字符串片段中匹配任意数量的字符,包括零个匹配。 对于匹配嵌套目录下的文件很有用。请确保适当地限制带有两个星号的 glob 的使用,以避免匹配大量不必要的目录。

下面这个 glob 被适当地限制在 scripts/ 目录下。它将匹配类似 scripts/index.jsscripts/nested/index.jsscripts/nested/twice/index.js 的文件。

'scripts/**/*.js'

desc

dest() 接受一个输出目录作为参数,并且它还会产生一个 Node 流(stream),通常作为终止流(terminator stream)。当它接收到通过管道(pipeline)传输的文件时,它会将文件内容及文件属性写入到指定的目录中。gulp 还提供了 symlink() 方法,其操作方式类似 dest(),但是创建的是链接而不是文件( 详情请参阅 symlink() )。

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

series

将任务函数和/或组合操作组合成更大的操作,这些操作将按顺序依次执行。对于使用 series()parallel() 组合操作的嵌套深度没有强制限制。

用法

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

function javascript(cb) {
// body omitted
cb();
} function css(cb) {
// body omitted
cb();
} exports.build = series(javascript, css);

parallel

将任务功能和/或组合操作组合成同时执行的较大操作。对于使用 series()parallel() 进行嵌套组合的深度没有强制限制。

用法

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

function javascript(cb) {
// body omitted
cb();
} function css(cb) {
// body omitted
cb();
} exports.build = parallel(javascript, css);

watch

监听 globs 并在发生更改时运行任务。任务与任务系统的其余部分被统一处理。

用法

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

watch(['input/*.js', '!input/something.js'], function(cb) {
// body omitted
cb();
});

启动项目并热更新

安装

npm install --save-dev browser-sync

使用

gulpfile.js 文件中配置如下代码

const { series, parallel, src, dest, watch } = require("gulp");
const browserSync = require("browser-sync"); // 启动项目
const reload = browserSync.reload; // 更新页面 // 启动项目
function server() {
browserSync({
notify: false, // 关闭通知,页面右上角不会出现弹框
port: 3000, // 启动 3000 端口
server: {
baseDir: ["src"], // 配置根目录,在这个根目录下启动服务器
},
callbacks: {
// 项目启动成功后执行的方法
ready: () => {
console.log("开始监控开发文件夹");
// 设置要监控的页面,当被监控页面发生变化时执行重载方法
const watcher = watch(["src/**/*.html", "src/**/*.js", "src/**/*.css"]);
// 监听到变化后执行
watcher.on("change", () => {
// 页面变化后执行重载方法
reload();
});
},
},
});
} // 公开 server 任务,执行 gulp server 运行启动任务
exports.server = server;

运行

然后在控制台中运行 gulp server

运行成功如上图所示,同时自动浏览器

压缩 HTML

安装

npm install --save-dev gulp-htmlmin gulp-html-replace

配置

下面用到的 gulp-html-replace 替换文件引用地址,我们需要在 html 中需要替换的地方通过注释形式来告诉配置文件我要替换那个地址

标记格式,标记后我们就可以通过标记的名称来对引用地址进行替换

<!-- build:css -->
<link rel="stylesheet" href="./public/css/index.css">
<!-- endbuild --> <!-- build:js -->
<script src="./public/js/index.js"></script>
<!-- endbuild -->

配置代码

const { series, parallel, src, dest, watch } = require("gulp");
const htmlmin = require("gulp-htmlmin"); // 压缩html
const htmlreplace = require("gulp-html-replace"); // 替换文件引用地址
// 配置压缩html的规则
const indexOptions = {
removeComments: true, // 清除html注释
collapseWhitespace: true, // 压缩html
collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> -> <input checked />
removeEmptyAttributes: true, // 删除所有空格作为属性值 <inpit id=""/> -> <inpit/>
minifyCss: true, // 压缩页面中的css
minifyJs: true, // 压缩页面中的js
}; // 压缩打包html
function html() {
return src(["src/view/**/*.html"])
.pipe(htmlmin(indexOptions)) // 使用上面定义的压缩配置进行压缩html
.pipe(dest("dist/html/")); // 将文件写入到 dist/html/ 目录下
}
// 单独处理一下 index.html
function indexhtml() {
return src("src/index.html")
.pipe(
htmlreplace({
// 替换标记的路径
css: "css/index.css",
js: "js/index.min.js",
})
)
.pipe(htmlmin(indexOptions)) // 使用上面定义的压缩配置进行压缩html
.pipe(dest("dist/"));
}

压缩 CSS

安装

npm install --save-dev gulp-csso @babel/core

配置

const { series, parallel, src, dest, watch } = require("gulp");
const csso = require("gulp-csso"); // 压缩css // 压缩css
function css() {
return src("src/public/css/**/*.css").pipe(csso()).pipe(dest("dist/css"));
}

压缩 JS

安装

npm install --save-dev gulp-uglify gulp-babel gulp-rename gulp-string-replace

配置

const { series, parallel, src, dest, watch } = require("gulp");
const babel = require("gulp-babel"); // 支持es6以及模块化
const uglify = require("gulp-uglify"); // 压缩js代码
const rename = require("gulp-rename"); // 重命名文件
const replace = require("gulp-string-replace"); // 替换字符串 // 压缩js
function js() {
// 即使这个任务不需要回调,但也要有一个默认的回调方法,也可以return
// cb();
return src("src/public/js/*.js")
.pipe(babel())
.pipe(uglify()) // 压缩js代码
.pipe(replace(/assetApi/g, "https://www.gulpjs.com.cn")) // 替换代码中的 "assetApi"
.pipe(rename({ extname: ".min.js" })) // 将匹配到的文件重名名为xxx.main.js
.pipe(dest("dist/js/")); // 将文件写入到 dist/js/ 目录下
}

清空文件

安装

npm install --save-dev gulp-clean

配置

const { series, parallel, src, dest, watch } = require("gulp");
const clean = require("gulp-clean"); // 清空文件夹 // 清空dist文件夹
function cleans() {
// 获取到dist文件夹下面的所有文件,进行清空操作
return src(["./dist/*"]).pipe(clean());
}

打包代码

新建打包任务

/**
* 打包任务
* 私有任务也可以在 series 组合中使用
* series 是顺序执行多个任务
* parallel 是平行执行多个任务
*/
const build = series(cleans, js, html, indexhtml, css, function (cb) {
// 必须要有一个回调方法
cb();
}); // 公开 build 任务,执行 gulp build 运行打包任务
exports.build = build;

在控制台执行 gulp build

运行成功后会在根目录下自动生成一个 dist 文件夹

我们打开打包好的文件,可以看到配置的一些规则都是生效的

我们在文件中直接双击打开 dist/index.html

页面可以正常的显示出来,表示路径的引用也是正确的

完整的开发依赖包

"devDependencies": {
"@babel/core": "^7.14.3",
"browser-sync": "^2.26.14",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-clean": "^0.4.0",
"gulp-csso": "^4.0.1",
"gulp-html-replace": "^1.6.2",
"gulp-htmlmin": "^5.0.1",
"gulp-rename": "^2.0.0",
"gulp-string-replace": "^1.1.2",
"gulp-uglify": "^3.0.2",
"gulp-webserver": "^0.9.1"
}

完整的配置代码

const { series, parallel, src, dest, watch } = require("gulp");
const babel = require("gulp-babel"); // 支持es6以及模块化
const uglify = require("gulp-uglify"); // 压缩js代码
const rename = require("gulp-rename"); // 重命名文件
const clean = require("gulp-clean"); // 清空文件夹
const csso = require("gulp-csso"); // 压缩css
const htmlmin = require("gulp-htmlmin"); // 压缩html
const gulpServer = require("gulp-webserver"); // 启动项目
const htmlreplace = require("gulp-html-replace"); // 替换文件引用地址
const replace = require("gulp-string-replace"); // 替换字符串
const browserSync = require("browser-sync"); // 启动项目
const reload = browserSync.reload; // 更新页面 // 配置压缩html的规则
const indexOptions = {
removeComments: true, // 清除html注释
collapseWhitespace: true, // 压缩html
collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> -> <input checked />
removeEmptyAttributes: true, // 删除所有空格作为属性值 <inpit id=""/> -> <inpit/>
minifyCss: true, // 压缩页面中的css
minifyJs: true, // 压缩页面中的js
}; // 清空dist文件夹
function cleans() {
// 获取到dist文件夹下面的所有文件,进行清空操作
return src(["./dist/*"]).pipe(clean());
} // 压缩js
function js() {
// 即使这个任务不需要回调,但也要有一个默认的回调方法,也可以return
// cb();
return src("src/public/js/*.js")
.pipe(babel())
.pipe(uglify()) // 压缩js代码
.pipe(replace(/assetApi/g, "https://www.gulpjs.com.cn")) // 替换代码中的 "assetApi"
.pipe(rename({ extname: ".min.js" })) // 将匹配到的文件重名名为xxx.main.js
.pipe(dest("dist/js/")); // 将文件写入到 dist/js/ 目录下
} // 压缩打包html
function html() {
return src(["src/view/**/*.html"])
.pipe(htmlmin(indexOptions)) // 使用上面定义的压缩配置进行压缩html
.pipe(dest("dist/html/")); // 将文件写入到 dist/html/ 目录下
} // 单独处理一下 index.html
function indexhtml() {
return src("src/index.html")
.pipe(
htmlreplace({
// 从注释标记中获取要替换的路径
css: "css/index.css",
js: "js/index.min.js",
})
)
.pipe(htmlmin(indexOptions)) // 使用上面定义的压缩配置进行压缩html
.pipe(dest("dist/"));
} // 压缩css
function css() {
return src("src/public/css/**/*.css").pipe(csso()).pipe(dest("dist/css"));
} // 启动项目
function server() {
browserSync({
notify: false, // 关闭通知,页面右上角不会出现弹框
port: 3000, // 启动 3000 端口
server: {
baseDir: ["src"], // 配置根目录,在这个根目录下启动服务器
},
callbacks: {
// 项目启动成功后执行的方法
ready: () => {
console.log("开始监控开发文件夹");
// 设置要监控的页面,当被监控页面发生变化时执行重载方法
const watcher = watch(["src/**/*.html", "src/**/*.js", "src/**/*.css"]);
// 监听到变化后执行
watcher.on("change", () => {
// 页面变化后执行重载方法
reload();
});
},
},
});
} /**
* 打包任务
* 私有任务也可以在 series 组合中使用
* series 是顺序执行多个任务
* parallel 是平行执行多个任务
*/
const build = series(cleans, js, html, indexhtml, css, function (cb) {
// 必须要有一个回调方法
cb();
}); // 公开 server 任务,执行 gulp server 运行启动任务
exports.server = server;
// 公开 build 任务,执行 gulp build 运行打包任务
exports.build = build;

使用gulp搭建项目的更多相关文章

  1. 使用gulp搭建一个传统的多页面前端项目的开发环境

    1.简介 使用gulp搭建一个传统的多页面前端项目的开发环境 支持pug scss es6编译支持 支持开发环境和打包生成sourceMap 支持文件变动自动刷新浏览器,css是热更新(css改动无需 ...

  2. 利用gulp搭建less编译环境

       什么是less? 一种 动态 样式 语言. LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承, 运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, ...

  3. 使用gulp搭建less编译环境

    什么是less? 一种 动态 样式 语言. LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承, 运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, Fi ...

  4. ASP.NET MVC搭建项目后台UI框架—1、后台主框架

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  5. ASP.NET MVC搭建项目后台UI框架—11、自动加载下拉框查询

    ASP.NET MVC搭建项目后台UI框架—1.后台主框架 需求:在查询记录的时候,输入第一个字,就自动把以这个字开头的相关记录查找出来,输入2个字就过滤以这两个子开头的记录,依次类推. 突然要用到这 ...

  6. ASP.NET MVC搭建项目后台UI框架—2、菜单特效

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  7. ASP.NET MVC搭建项目后台UI框架—3、面板折叠和展开

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  8. ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  9. ASP.NET MVC搭建项目后台UI框架—5、Demo演示Controller和View的交互

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

随机推荐

  1. java例题_42 求满足809*??=800*??+9*??+1的??的值

    1 /*42 [程序 42 求数字] 2 题目:809*??=800*??+9*??+1 3 其中??代表的两位数,8*??的结果为两位数,9*??的结果为 3 位数.求??代表的两位数,及 809* ...

  2. Python的flask接收前台的ajax的post数据和get数据

    ajax向后台发送数据: ①post方式 ajax: @app.route("/find_worldByName",methods=['POST']) type:'post', d ...

  3. 如何从 dump 文件中提取出 C# 源代码?

    一:背景 相信有很多朋友在遇到应用程序各种奇葩问题后,拿下来一个dump文件,辛辛苦苦分析了大半天,终于在某一个线程的调用栈上找到了一个可疑的方法,但 windbg 常常是以 汇编 的方式显示方法代码 ...

  4. Dynamics CRM的Associate功能

    Dynamics CRM有一种特殊的关联关系叫Associate,一般常见于为用户分配角色.给团队添加用户.团队添加角色.队列添加用户等等.在一些特定场景下我们不可能把所有的操作都通过手动来完成尤其是 ...

  5. Dynamics CRM安装教程九(续):自建证书的CRM项目客户端设置CRM访问

    配置完IFD之后就可以为客户端电脑配置访问CRM了首先到CA证书服务器中把证书下载下来,打开CA服务器的浏览器,输入地址http://stg-ad/certsrv/ 其中stg-ad是机器名之后点击下 ...

  6. resultMap结果集映射解决属性名和字段不一致问题

    解决属性名和字段名不一致的问题 1.出现的问题 数据库中的字段 ​ 新建一个项目,拷贝之前的,测试实体类与数据库字段不一致的情况 public class User { private int id; ...

  7. 自动化kolla-ansible部署ubuntu20.04+openstack-victoria之裸金属-20

    自动化kolla-ansible部署ubuntu20.04+openstack-victoria之裸金属-20 欢迎加QQ群:1026880196 进行交流学习 近期我发现网上有人转载或者复制原创博客 ...

  8. JetBrains系列IDE无法输入中文

    1 问题描述 环境Linux+fcitx,JetBrains的IDE无法输入中文,包括IDEA,PyCharm,WebStorm,CLion等等. 2 解决方案 Linux下一般使用fcitx进入中文 ...

  9. yolov2算法浅见

    因为最近在复习yolo系列的算法,就借着这个机会总结一下自己对这个算法的理解,由于是第一次写算法类的博客,文中有什么错误和行文不通的地方还希望大家指正. yolov2与yolov1有很多改变. 最重要 ...

  10. Java代理简述

    1.什么是代理? 对类或对象(目标对象)进行增强功能,最终形成一个新的代理对象,(Spring Framework中)当应用调用该对象(目标对象)的方法时,实际调用的是代理对象增强后的方法,比如对功能 ...