前言
虽然说现在webpack已经很强大了,但是gulp也没有完全退出历史舞台,有些时候面试还会问到有没有使用gulp,如果说你碰到过gulp的相关,希望这篇文章对你会有小小的帮助!
平时学习的语雀地址
gulp是什么?
gulp.js 是一个自动化构建工具,用于自动化Web开发中涉及的耗时和重复性任务,Gulp.js 是基于 Node.js 构建的,利用 Node.js 流的威力,你可以快速构建项目。
gulp的优点
- 代码优于配置、node最佳实践、精简的API集,gulp让工作前所未有的简单。
- 基于node强大的流(stream)能力,gulp在构建过程中并不把文件立即写入磁盘,从而提高了构建速度。
- 遵循严格的准则,确保我们的插件结构简单、运行结果可控。
gulp的缺点
插件bug比较难处理。
准备工作
step1.检查环境配置
我们先来检查一下检查 node、npm 或者 npx 或者 yarn是否正确安装。
新的node和npm用户可能会遇到权限问题。这些问题EACCESS在安装过程中以错误的形式显示。如果发生这种情况,请参考《npm指南》以修复权限。
step2.安装 gulp 命令行工具
安装命令
npm install --global gulp-cli
step3.创建项目目录
这里我们将创建一个名为kds-gulp项目为例。
step4.初始化package.json
cd到我们的项目目录(kds-gulp)执行以下命令创建package.json文件,我这里使用yarn命令
//使用npm命令也可以
yarn init
step5.安装gulp开发依赖
安装命令
yarn add --save-dev gulp
step6.检查版本
执行命令检查我们是否成功安装插件
gulp -v
step7.建立gulpfile.js文件
gulp也需要一个文件作为它的入口文件,在gulp中这个文件叫做gulpfile.js。
step8.准备项目资源
在项目路径下新建src文件,将我们所需要的开发文件和静态资源放入其中,下面是我所准备的静态资源,之后将对每一种类型的文件如何使用gulp进行自动化操作进行详尽的说明。
大家如果想自己尝试一下的话,按照文件后缀名自己准备资源文件即可。
└── kds-gulp ································· project root
├─ public ········································· static folder
│ └─ favicon.ico ································· static file (unprocessed)
├─ src ············································ source folder
│ ├─ assets ······································ assets folder
│ │ ├─ fonts ···································· fonts folder
│ │ │ └─ pages.ttf ····························· font file (imagemin)
│ │ ├─ images ··································· images folder
│ │ │ └─ logo.png ······························ image file (imagemin)
│ │ ├─ scripts ·································· scripts folder
│ │ │ └─ main.js ······························· script file (babel / uglify)
│ │ └─ styles ··································· styles folder
│ │ ├─ _variables.scss ······················· partial sass file (dont output)
│ │ └─ main.scss ····························· entry scss file (scss / postcss)
│ ├─ layouts ····································· layouts folder
│ │ └─ basic.html ······························· layout file (dont output)
│ ├─ partials ···································· partials folder
│ │ └─ header.html ······························ partial file (dont output)
│ ├─ about.html ·································· page file (use layout & partials)
│ └─ index.html ·································· page file (use layout & partials)
├─ .csscomb.json ·································· csscomb config file
├─ .editorconfig ·································· editor config file
├─ .gitignore ····································· git ignore file
├─ .travis.yml ···································· travis ci config file
├─ CHANGELOG.md ··································· repo changelog
├─ LICENSE ········································ repo license
├─ README.md ······································ repo readme
├─ gulpfile.js ···································· gulp tasks file
├─ package.json ··································· package file
└─ yarn.lock ······································ yarn lock file
开始上手
我们对资源文件进行处理的逻辑代码需要卸载gulpfile.js中
step1.安装gulp-load-plugins插件
先安装这个模块主要是为了让代码变得简洁,之后我们需要require许多插件,做好提前量,(如果还不知道 gulp-load-plugins有什么作用请去常用插件中寻找)。
安装命令
yarn add gulp-load-plugins --dev
step2.样式编译
查看项目kds-gulp的项目目录,在src/assests/styles存在scss样式文件,但是生产环境无法识别这些样式文件,我们需要把它转换成可识别的css文件。
- 安装gulp-sass插件。
- 注意:以_开头的scss文件会被忽略掉,不会被转换。
- 将转译后的文件输出到temp临时目录,以便后边做合并操作。
- 运行 gulp style测试。
安装命令:
yarn add gulp-sass --dev
编写gulpfile.js中的代码块: 如果想要在输出目录保持输入目录的文件层级加上{base: 'src'}即可
const style = () =>{
return src('src/assets/styles/*.scss',{base: 'src'})
.pipe(plugins.sass())
.pipe(dest('temp'))
}
module.exports = {
style
}
step3.脚本编辑
查看项目kds-gulp的项目目录,在src/assests/scripts存在js脚本文件,我开实际开发中可能会使用es6语法,生产环境中对es6兼容性可能会存在问题,我们需要通过babel把es6转换成es5语法,具体操作如下:
- 安装gulp-babel插件。
- 编写转换函数。
- 将转译后的文件输出到temp临时目录,以便后边做合并操作。
- 运行 gulp scripts测试。
安装命令:
yarn add gulp-babel --dev
编写代码:
const scripts = () =>{
return src('src/assets/scripts/*.js',{base: 'src'})
.pipe(plugins.babel({presets: ['@babel/env']}))
.pipe(dest('temp'))
}
//将目标文件下所有js文件转换流传送给babel处理,最后输出到temp目录
module.exports = {
scripts
}
step5.资源文件处理
现在开始对我们的图片字体等静态资源进行压缩处理,并进行缓存。
- 安装gulp-imagemin插件和gulp-cache插件。
- 压缩图片,减少图片体积。
- 因为压缩图片比较耗时,我们只需要压缩修改的图片,没有修改的直接从缓存中读取。
- 编写转换函数。
- 运行 gulp img和gulp font测试。
安装命令
yarn add gulp-cache --dev
yarn add gulp-imagemin --dev
编写代码
const img = () =>{
return src('src/assets/images/**',{base: 'src'}).pipe(plugins.cache(
plugins.imagemin({
progressive : true,//是否渐进的优化
svgoPlugins : [{removeViewBox:false}],//svgo插件是否删除幻灯片
interlaced : true //是否各行扫描
})
)).pipe(dest('dist'))
}
module.exports = {
img
}
字体样式文件同理
const font = () => {
return src('src/assets/fonts/**',{base: 'src'})
.pipe(plugins.imagemin())
.pipe(dest('dist'))
}
module.exports = {
font
}
step6.额外文件
对于非src下其他相关文件也同样需要打包到dist目下,例如public目录下,也需要处理一下。
const extra = () =>{
return src('public/**',{base: 'public'})
.pipe(dest('dist'))
}
module.exports = {
extra
}
step7.组合执行命令
如果我们一个个去敲命令执行转换操作,麻烦且繁琐,使用parallel(),series()去进行组合嵌套,parallel,series可以去官网api查看,这里不多做叙述。
- 使用parallel(),series()将函数组合到一起执行。
- 生成dist前,执行clean先清除一遍以防有缓存。
- 将temp目录下的文件进行合并压缩输出到dist目录。
- 了解合并压缩过程请跳到上线准备章节。
- 运行 gulp build测试。
const clean = () =>{
return src(['dist','temp'])
.pipe(plugins.clean())
}//清除已存在的dist包
const compile = parallel([style,scripts,page]);//合并step2,3,4的操作
//上线前端操作
const build = series(clean, parallel(series(complie, useref),extra, image, font))//清除dist包后,执行step1,2,3,4,5,6的操作
module.exports = {
build
}
测试调试
开发阶段我们需要不断修改代码并展现在浏览器中供我们调试开发,并且我们希望这种方式是“热更新的形式”。 我们可以通过gulp创建一个服务器来满足我们的开发需求。
step1.创建基础服务器
- 安装browser-sync模块。
- 通过browser-sync的create区创建一个服务器。
- 编写我们的serve函数,并且初始化我们的服务器。
- gulp build过后执行 gulp serve测试。
安装命令
yarn add browser-sync --dev
创建服务器
const borwserSync = require('browser-sync')
const bs = borwserSync.create()//自动打开浏览器
const serve = () => {
bs.init({
notify: false,
port: 3000,//启动浏览器的端口号
files:'dist/**',//监听dist文件下有改动的时候刷新页面
server: {
baseDir: ['dist','src','public'],//如果找不到目标文件,会按着数组目录依次查找
routes: {
'/node_modules': 'node_modules' //自动映射到项目下的node_modules
}
}
})
}
step2.监听文件更改
上述操作的确可以动态的跟新服务器,但是仅限于dist目录发生改变的时候,这样我们不得不一遍一遍打包执行build操作,很麻烦,所以我们需要简化这步操作。
- 通过watch()监听文件改变,来动态的执行我们对应的方法。
- 合并命令行。
- 执行gulp develop测试。
const serve = () => {...
//第一个参数为监听路径,第二个为对应执行的处理函数。
watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
watch([
'src/assets/images/**',
'src/assets/fonts/**',
'public/**'
], bs.reload)
}
const compile = parallel([style,scripts,page]);//合并step2,3,4的操作
//将打包命令和服务器启动整合到一起
const develop = series(compile,serve)
module.exports = {
compile,
develop
}
上线准备
上线前我们需要把html中的文件进行合并处理。这里要用到useref。
step1.合并
- gulp-useref将HTML引用的多个CSS和JS合并起来,减小依赖的文件个数,从而减少浏览器发起的请求次数。
- gulp-useref根据注释将HTML中需要合并压缩的区块找出来,对区块内的所有文件进行合并。
- 它只负责合并,不负责压缩!
安装命令
yarn add gulp-useref --dev
编写代码
const useref = {
rerurn src('temp/*.html',{base: 'temp'}).pipe(plugins.useref({searchPath:['temp','.'] }))
.pipe(dest('dist'))
}
step2.压缩
- 我们需要对js、css、html进行压缩。
- 安装gulp-uglify、gulp-htmlmin、gulp-clean-css模块
- 使用if插件对当前环境进行判断,执行不同压缩。
安装命令
yarn add gulp-htmlmin --dev
yarn add gulp-uglify --dev
yarn add gulp-clean-css --dev
yarn add gulp-if --dev
编写代码
const useref = {
rerurn src('temp/*.html',{base: 'temp'}).pipe(plugins.useref({searchPath:['temp','.'] }))
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true,
minifyCSS: true, //页面里的style和js脚本压缩
minifyJS: true
}))) //html
.pipe(dest('dist'))
}
常用插件
这里介绍一些实际开发中经常用到的插件,gulp插件库已经很丰富了,如果有需要可以去官网查询。 gulpjs.com/plugins/
gulp-babel
描述:将ES6代码编译成ES5。
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.src('./js/index.js')
.pipe(babel({
presets: ['@babel/preset-env']
}))
.pipe(gulp.dest('./dist'))
gulp-sass
描述:编译sass。
const sass = require('gulp-sass');
gulp.src('./sass/**/*.scss')
.pipe(sass({
outputStyle: 'compressed' // 配置输出方式,默认为nested
}))
.pipe(gulp.dest('./dist/css'));
gulp-rename
描述:用来重命名文件流中的文件。
var rename = require("gulp-rename");
gulp.src('./hello.txt')
.pipe(rename('gb/goodbye.md')) // 直接修改文件名和路径
.pipe(gulp.dest('./dist'));
gulp.src('./hello.txt')
.pipe(rename({
dirname: "text", // 路径名
basename: "goodbye", // 主文件名
prefix: "pre-", // 前缀
suffix: "-min", // 后缀
extname: ".html" // 扩展名
}))
.pipe(gulp.dest('./dist'));
gulp-load-plugins
- 要使用gulp的插件,首先得用require来把插件加载进来。
- 如果要加载很多,代码变得又臭又长。
- gulp-load-plugins插件正是用来解决这个问题。
var gulp = require('gulp'),
//一些gulp插件,abcd这些命名只是用来举个例子
a = require('gulp-a'),
b = require('gulp-b'),
c = require('gulp-c'),
d = require('gulp-d'),
//更多的插件...
z = require('gulp-...');
自从有了它有了它以后
// package.json
"devDependencies": {
"gulp": "^3.9.1",
"gulp-concat": "^2.6.1",
"gulp-rename": "^1.2.2",
"gulp-uglify": "^2.0.1"
}
// gulpfile.js
var plugins = require('gulp-load-plugins')(); // $ 是一个对象,加载了依赖里的插件
gulp.src('./**/*.js')
.pipe(plugins.concat('all.js')) // 使用插件就可以用$.PluginsName()
.pipe(plugins.uglify())
.pipe(plugins.rename('all.min.js'))
.pipe(gulp.dest('./dist'))
gulp-clean-css
描述:压缩css文件,减小文件大小。
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.src('./js/index.js')
.pipe(babel({
presets: ['@babel/preset-env']
}))
.pipe(gulp.dest('./dist'))
gulp-cache
- 监控到图片被改变了,替换了,才去压缩。
- 如果仅仅是改变了图片名字,则不会被替换。
var cache = require('gulp-cache');
gulp.task('img', function (
){
gulp.src('./src/images/*.{jpg|jpeg|png|gif}',)
.pipe(
cache(
imagemin({
progressive : true,//是否渐进的优化
svgoPlugins : [{removeViewBox:false}],//svgo插件是否删除幻灯片
interlaced : true //是否各行扫描
})
)
)
.pipe(
gulp.dest('./src/images/*.{jpg|jpeg|png|gif}')
)
});
gulp-swig
描述:swig 一个简单的,强大的,可扩展的JavaScript模板引擎。
var swig = require('gulp-swig');
var opts = {
data: {
headline: "Welcome"
}
};
gulp.task('templates', function() {
gulp.src('./lib/*.html')
.pipe(swig(opts))
.pipe(gulp.dest('./dist/'))
});
gulp-imagemin
描述:压缩图片。
var imagemin = require('gulp-imagemin');
gulp.src('./img/*.{jpg,png,gif,ico}')
.pipe(imagemin())
.pipe(gulp.dest('./dist/img'))
gulp-useref
描述:合并文件。
var gulp = require('gulp'),
useref = require('gulp-useref');
gulp.task('default', function () {
return gulp.src('app/*.html')
.pipe(useref())
.pipe(gulp.dest('dist'));
});
html中
需要配合构建注释使用
<html>
<head>
<!-- build:css css/combined.css -->
<link href="css/one.css" rel="stylesheet">
<link href="css/two.css" rel="stylesheet">
<!-- endbuild -->
</head>
<body>
<!-- build:js scripts/combined.js -->
<script type="text/javascript" src="scripts/one.js"></script>
<script type="text/javascript" src="scripts/two.js"></script>
<!-- endbuild -->
</body>
</html>
gulp-uglify
描述:用来压缩js文件,使用的是uglify引擎。
var gulp = require('gulp'),
uglify = require("gulp-uglify");
gulp.task('minify-js', function () {
gulp.src('js/*.js') // 要压缩的js文件
.pipe(uglify()) //使用uglify进行压缩,更多配置请参考:
.pipe(gulp.dest('dist/js')); //压缩后的路径
});
gulp-minify-css
描述:要压缩css文件时可以使用该插件。
var gulp = require('gulp'),
minifyCss = require("gulp-minify-css");
gulp.task('minify-css', function () {
gulp.src('css/*.css') // 要压缩的css文件
.pipe(minifyCss()) //压缩css
.pipe(gulp.dest('dist/css'));
});
gulp-htmlmin
描述:用来压缩html文件。
var gulp = require('gulp'),
minifyHtml = require("gulp-htmlmin");
gulp.task('minify-html', function () {
gulp.src('html/*.html') // 要压缩的html文件
.pipe(minifyHtml()) //压缩
.pipe(gulp.dest('dist/html'));
});