自动化构建工具(二)Gulp

一、快速入门

1.1 检查 node、npm 和 npx 是否正确安装

node --version
npm --version
npx --version

在这里插入图片描述

1.2 安装 gulp 命令行工具

npm install --global gulp-cli

1.3 创建项目目录并进入

npx mkdirp my-project
cd my-project

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

npm init

上述命令将指引你设置项目名、版本、描述信息等。
在这里插入图片描述

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

npm install --save-dev gulp

在这里插入图片描述

1.6 检查 gulp 版本

gulp --version

在这里插入图片描述
1.7 创建 gulpfile 文件
利用任何文本编辑器在项目大的根目录下创建一个名为 gulpfile.js 的文件,并在文件中输入以下内容:

function defaultTask(cb) {
    
    
  // place code for your default task here
  cb();
}
exports.default = defaultTask

1.8 测试
在项目根目录下执行 gulp 命令:

gulp

1.9输出结果
默认任务(task)将执行,因为任务为空,因此没有实际动作。
在这里插入图片描述
1.10目录结构
在这里插入图片描述

二、安装依赖


npm i --save-dev gulp        // gulp自动化构建工具
npm i --save-dev gulp-uglify //js压缩
npm i --save-dev gulp-concat //文件合并
npm i --save-dev gulp-jshint //js语法检测
npm i --save-dev gulp-rename //文件重命名
npm i --save-dev gulp-sass //sass编译工具
npm i --save-dev gulp-minify-css //css压缩
npm i --save-dev del       //文件删除
// 以下三选一
npm i --save-dev gulp-connect       // 自动刷新页面
npm i --save-dev  browser-sync       // 自动刷新页面

三、配置gulpfile.js

// 定义依赖项和插件
const gulp=require('gulp');
const  uglify=require('gulp-uglify'); //js压缩
const  concat=require('gulp-concat'); //文件合并
const jshint = require('gulp-jshint'); //js语法检测
const rename = require('gulp-rename'); // 重命名
const sass = require('gulp-sass'); // 编译scss
const  minifycss = require('gulp-minify-css'); // 压缩css
// const livereload = require('gulp-livereload'); // 自动刷新页面
const  del = require('del'); //文件删除
const connect = require('gulp-connect'); // 自动刷新页面
 
gulp.task('server', function() {
    
    
  connect.server({
    
    
    port: 8080, //指定端口号,在浏览器中输入localhost:8080就可以直接访问生成的html页面
    root: './', //指定html文件起始的根目录
    livereload: true //启动实时刷新功能(配合上边的connect.reload()方法同步使用)
  });
});
 
// 定义名为 "my-task" 的任务压缩js
gulp.task('my-task-js', function(){
    
    
  gulp.src('./js/*.js')
    .pipe(jshint())
    .pipe(uglify())
    .pipe(concat('all.js'))
    .pipe(rename({
    
    suffix: '.min'}))
    .pipe(gulp.dest('./dist/js'))
    .pipe(connect.reload())
});
 
 
// 定义名为 "my-task-css" 的任务编译scss压缩css
gulp.task('my-task-css', function() {
    
    
  gulp.src('./css/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(concat('all.css'))
    .pipe(rename({
    
    suffix: '.min'}))
    .pipe(minifycss())
    .pipe(connect.reload())
    .pipe(gulp.dest('./dist/css'))
 
});
 
gulp.task('html', function(){
    
    
  gulp.src('*.html')
    .pipe(gulp.dest('dist/html'))
    .pipe(connect.reload())
})
//执行压缩前,先删除以前压缩的文件
gulp.task('clean', function() {
    
    
  return del(['./dist/css/all.css', './dist/css/all.min.css', './dist/all.js','./dist/all.min.js', './dist/html'])
});
// 定义默认任务
 
gulp.task('default',['clean'],function() {
    
    
  gulp.start('my-task-js', 'my-task-css', 'watch', 'server' );
});
// 任务监听
gulp.task('watch', function() {
    
    
  // Watch.js files
  gulp.watch('./js/*.js', ['my-task-js']);
  // Watch .scss files
  gulp.watch('./css/*.scss', ['my-task-css']);
  // Watch .html files
  gulp.watch('./*.html', ['html']);
  // Watch any files in dist/, reload on change
  // gulp.watch(['dist/!**']).on('change', livereload.changed);
});


3.1、讲解gulpfile.js

// ...
// 定义名为 "my-task" 的任务压缩js
gulp.task('my-task-js', function(){
    
    
  gulp.src('./js/*.js')
    .pipe(jshint()) //js检测
    .pipe(uglify()) //js压缩
    .pipe(concat('all.js')) //合并为all.js
    .pipe(rename({
    
    suffix: '.min'})) // 重命名为all.mim.js
    .pipe(gulp.dest('./dist/js')) //输出到/dist/js目录
    .pipe(connect.reload()) // 更新页面
});
// ...

gulp.task是gulp的api 定义一个使用 Orchestrator 实现的任务(task) 如上我们定义了my-task-jsmy-task-csshtmlcleandefaultwatchserver等任务,其中:

  • my-task-js 是将 符合所提供的匹配模式的js
    进行检测(gulp-jshint)压缩(gulp-uglify)合并(gulp-concat)重命名(gulp-rename)输出(gulp.dest)到/dist/js目录下;
  • my-task-css 是将
    符合所提供的匹配模式的sass进行编译(gulp-sass)压缩(gulp-uglify)合并(gulp-concat)重命名(gulp-rename)输出(gulp.dest)到/dist/css目录下;
  • html 是将 符合所提供的匹配模式的html进行监听,如果有变化则connect.reload()
  • clean 是如果任务重新启动时 删除旧文件;
  • default gulp默认启动的任务
  • watch gulp的api 监视文件,并且可以在文件发生改动时候做一些事情。它总会返回一个 EventEmitter 来发射=(emit)change 事件。
  • server 依赖gulp-connect启动一个服务器
gulp.task('server', function() {
    
    
  connect.server({
    
    
    port: 8080, //指定端口号,在浏览器中输入localhost:8080就可以直接访问生成的html页面
    root: './', //指定html文件起始的根目录
    livereload: true //启动实时刷新功能(配合上边的connect.reload()方法同步使用)
  });
});

3.2 js和css及html加点东西
js/helloworld.js

// helloworld.js
console.log('hello world')

css/index.scss

// index.scss
 
// 变量测试
$fontColor:  #red;
$backColor: aqua;
// 嵌套类测试
div {
    
    
  p {
    
    
    font-weight: bold;
    font-size: 20px;
    color: $fontColor;
  }
}
 
div{
    
    
  background: $backColor;
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>gulp-study</title>
	<link href=/dist/css/all.min.css rel=stylesheet>
</head>
<body>
	<div id="firstDiv">
		<p>我是gulp</p>
		<p>hello world</p>
	</div>
<p>我是p标签</p>
<p>我是p标签</p>
</body>
<script src="/dist/js/all.min.js"></script>
</html>
 

3.3运行

gulp

3.4报错

Gulp Error: Cannot find module 'jshint/src/cli';

在这里插入图片描述
3.4.1问题原因:

插件安装不完全,新版本gulp做了一些调整好像。。。。

3.4.2解决方法:

使用npm install --save-dev jshint gulp-jshint

而不是npm install --save-dev gulp-jshint

3.5报错

运行gulp项目报错:AssertionError: Task function must be specified。
gulp.start is not a function
Task function must be specified

各种报错

3.6解决

上面的代码是3.x的版本
实际我们安装的是4.x的版本
api不一致

3.6.11. 新Api引入

// v3.9
let gulp = require('gulp');

// v4.0
const {
    
     watch, src, dest, series } = require("gulp");

// 新引入的src,dest可替换老版的gulp.src和gulp.dest,代码更简洁
// watch是任务监听
// series是任务按顺序执行

3.6.2. 新的创建任务方式

// 下面以压缩图片插件 gulp-imagemin 为例

let imagemin = require('gulp-imagemin');

// v3.9
gulp.task('imagemin', () => {
    
    
  gulp.src('/path')
    .pipe(imagemin())
    .pipe(gulp.dest('/path'))
})

// 4.0
function minImage() {
    
    
    return src('/path')
            .pipe(imagemin())
            .pipe(dest('/path'))
}

// 新版本使用了函数和return进行任务设置,函数名不能和引入的插件变量名称重复

3.6.3 执行任务方式

// v3.9
gulp.task('default', [task1, task2])

// v4.0,taskFn是设置任务的函数名
function defaultTask() {
    
    
    return series(taskFn1, taskFn2, taskFn3);  // series让任务按顺序执行
}
export.default = defaultTask() // 输出控制台执行任务的名称

// 新版本的export.xxxx,这个xxxx就是在控制台中gulp执行任务的名称,可以同时export设置多个任务
// 例如export.dev= dev(),想执行dev函数中返回的任务就在控制台输入gulp dev加回车!,如果是export.build = build(),则在控制台输入gulp build加回车!,如果是export.default = default(),直接输入gulp回车即可,以此类推

3.6.4 watch和series Api

 // v3.9,老版本好像要安装一个queue的插件才可以实现按顺序执行任务
let watch = require('gulp-watch');
gulp.task('watch', () => {
    
    
  gulp.watch(['filePath1', 'filePath2'], [task1, task2]);
});

// 4.0
const {
    
     watch, series} = require('gulp');
function watchTask() {
    
    
    // 注意这里不需要使用return
    watch(['filePath1', 'filePath2'], series(taskFn1, taskFn2, taskFn3));
}

// 新版本直接引入watch即可实现任务监听功能,不用安装插件
// series也可以配合watch按顺序执行设置的任务函数

3.7运行gulp
在这里插入图片描述

页面js、css都有生效

3.8修改css,js,html文件查看结果

修改代码,不需要重新运行gulp

3.8.1修改css代码
在这里插入图片描述

3.8.2修改js代码
在这里插入图片描述
3.8.3修改html代码

在这里插入图片描述

四、优秀的完整代码

gulpfile.js

const {
    
     series, src, dest, watch } = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const sass = require('gulp-sass');
const cleanCss = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const fileinclude = require('gulp-file-include');
const imagemin = require('gulp-imagemin');
const connect = require('gulp-connect');
const rename = require('gulp-rename');
const babel = require('gulp-babel');
const del = require('del');
const precompile = require('gulp-copy-content');
const px2rem = require('gulp-px3rem');

sass.compiler = require('node-sass')

// 编译sass
function compileSass() {
    
    
	return src('./src/scss/*.scss')
		.pipe(sass().on('error', sass.logError))
		.pipe(dest('./src/css'))
}

// 编译ES6
function compileJS() {
    
    
	return src('./src/js/*.js')
		.pipe(babel({
    
    
			presets: ['@babel/env']
		}))
		.pipe(dest('./dist/js'))
}

// 添加浏览器前缀
function autoprefixerFn() {
    
    
	return src('./dist/css/*.css')
		.pipe(autoprefixer())
		.pipe(dest('./dist/css'))
}

// 压缩css文件
function cleanCssFn() {
    
    
	return src('./dist/css/*.css')
		.pipe(cleanCss({
    
    
			compatibility: 'ie8'
		}))
		.pipe(rename({
    
     suffix: '.min' }))
		.pipe(dest('./dist/css'))
}

// 压缩图片
function minImage() {
    
    
	return src('./src/images/*')
		.pipe(imagemin())
		.pipe(dest('./dist/images'))
}

// 复制html模板
function htmlFileinClude() {
    
    
	return src('./src/*.html')
		.pipe(fileinclude({
    
    
			prefix: '@@',
			basepath: '@file',
			context: {
    
    
				sideNav: [
					{
    
     name: '概述', url: 'index.html', iconCls: 'gaishu' },
					{
    
     name: '直播间', url: '###', iconCls: 'zhibojian' },
					{
    
     name: '导播台', url: '###', iconCls: 'daobotai' },
					{
    
     name: '商品', url: '###', iconCls: 'shangpin' },
					{
    
     name: '用户', url: '###', iconCls: 'yonghu' },
					{
    
     name: '数据', url: '###', iconCls: 'shuju' },
					{
    
     name: '资产', url: '###', iconCls: 'zichan' },
					{
    
     name: '营销', url: 'market.html', iconCls: 'shezhi' },
					{
    
     name: '设置', url: '###', iconCls: 'sucai' }
				]
			}
		}))
		.pipe(dest('./dist'))
}

// 删除文件和文件夹
function delFn(cb) {
    
    
	return del([
		'./dist/*.html',
		'./dist/css/*',
		'./dist/images/*',
		'./dist/js/*',
		'./dist/lib/*',
	], cb)
}

// 复制文件
function copyFile() {
    
    
	return src('./src/lib/**/*')
		.pipe(precompile({
    
    
			reg: /<!\-\-copyContent\s+"([^"]+)"\s+\-\->/g,  // 匹配的文件正则.
			baseSrc: '', // 设置根目录之后不需要编写完整的路径.
		}))
		.pipe(dest('./dist/lib'))
}

// 本地服务器
function devServer() {
    
    
	return connect.server({
    
    
		root: 'dist/',
		port: 8999,
		host: '0.0.0.0',
		livereload: true
	})
}

// 服务器重加载
function serverReload() {
    
    
	return src(['./src/*.html', './src/js/*.js', './src/scss/*.scss'])
		.pipe(connect.reload());
}

// 压缩JS代码
function uglifyFn() {
    
    
	return src('./dist/js/main.js', {
    
    allowEmpty: true})
		.pipe(uglify())
		.pipe(rename({
    
    suffix: '.min'}))
		.pipe(dest('./dist/js'))
}

// px转换rem
function px2remFn() {
    
    
	return src('./src/css/*.css')
		.pipe(px2rem({
    
    
			remUnit: 750
		}))
		.pipe(dest('./dist/css'))
}

// 监听任务
function watchFn() {
    
    
	watch(['./src/scss/*.scss', './src/js/*.js', './src/*.html', './images/*'], series(delFn, htmlFileinClude, compileJS, compileSass, px2remFn, autoprefixerFn, minImage, copyFile, serverReload));
}

// 开发环境
function defaultTask() {
    
    
	setTimeout(() => {
    
    
		watchFn();
	}, 1500);
	return series(delFn, htmlFileinClude, compileJS, compileSass, px2remFn, autoprefixerFn, minImage, copyFile, devServer);
}

// 生产环境
function buildTask() {
    
    
	return series(delFn, htmlFileinClude, compileJS, compileSass, px2remFn, autoprefixerFn, cleanCssFn, uglifyFn, minImage, copyFile);
}


exports.default = defaultTask();
exports.build = buildTask();

package.json


{
    
    
 "name": "gulp4config",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
    
    
   "start": "gulp",
   "build": "gulp build"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 "dependencies": {
    
    
   "@babel/core": "^7.4.5",
   "@babel/preset-env": "^7.4.5",
   "del": "^4.1.1",
   "gulp": "^4.0.2",
   "gulp-autoprefixer": "^6.1.0",
   "gulp-babel": "^8.0.0",
   "gulp-clean-css": "^4.2.0",
   "gulp-connect": "^5.7.0",
   "gulp-copy-content": "0.0.1",
   "gulp-file-include": "^2.0.1",
   "gulp-imagemin": "^6.0.0",
   "gulp-px3rem": "^0.3.0",
   "gulp-rename": "^1.4.0",
   "gulp-sass": "^4.0.2",
   "gulp-uglify": "^3.0.2",
   "node-sass": "^4.12.0"
 },
 "devDependencies": {
    
    }
}

五、总结

5.1gulp或grunt和webpack的区别

其实Webpack和另外两个并没有太多的可比性

  • Gulp/Grunt是一种能够优化前端的开发流程的工具,
  • WebPack是一种模块化的解决方案,不过Webpack的优点使得Webpack在很多场景下可以替代Gulp/Grunt类的工具。

Grunt和Gulp的工作方式是:

  • 在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。
  • Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

六、官网-很详细

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42580704/article/details/108366071