一、基本使用
(一)重要 API
gulp.src(filePath/PathArr)
用于读取文件。读取指定路径下所有文件,返回文件流对象
gulp.dest(filePath/PathArr)
输出文件。将指定的文件,输出都指定的目录下
gulp.wacth(filePath/PathArr,tasksFn)
监听指定路径下的,文件变化
注意:该方法的第二个参数,是个 Fn 或 tasks。
gulp.task(taskName,taskFunction)
官网已经不推荐使用该API注册 task了,推荐使用
exports创建 task。
注意:
1、之前版本task(taskName,[...tasks],fn)在 5.X 版本是错误的。5.X 版本的是task([taskName], taskFunction)。第二个参数要么是一个函数,要么是由series()或parallel()创建的tasks。
2、taskFunction中的 回调函数done一定要在函数最后调用一次,表示该任务完成 了。否则,整个代码执行会一直暂停在这里。
gulp.series()
将任务函数和/或组合操作组合成更大的操作,这些操作将按顺序依次执行
gulp.parallel()
将任务功能和/或组合操作组合成同时执行的较大操作。
(二)使用注意点
在 API 中 介绍过,gulp.task(taskName,taskFunction) 中的 taskFunction 函数中的参数是done函数。但是,并不是所有注册的 task,都有done该函数(exports 创建的任务也是一样的)。
那什么时候,task 需要 在末尾调用 done呢?
如果 返回的是
gulp内置方法的操作,则该任务不需要 调用done。否则,该任务需要调用done,表示该任务完成。
- 举例
function htmlminTask() {
return gulp.src('../src/index.html')
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(gulp.dest('../dist'))
}
module.exports = {
htmlminTask
}
上述代码,是处理 index.html 文件的任务,但是内部返回的是gulp.src开始的链式操作,所以不需要调用 done 函数。
const browserTask = (done) => {
browserSync.init({
server: {
baseDir: "../dist",
},
});
if(typeof done === 'function') {
done()
}
};
上述代码,是创建一个浏览器服务的代码。因为内部没有返回 gulp 内置方法的操作,因此需要调用 done。
二、文件处理
(一)目录结构
├─build
├─build.js
├─build-html.js
├─build-style.js
├─build-js.js
├─build-server.js
├─only-js.js
├─only-html.js
└─only-style.js
├─src
├─css
├─js
└─index.html
└─package.json
- package.json
"scripts":{
"build": "gulp --gulpfile build/build.js",
"build:js": "gulp --gulpfile build/only-js.js", // 单独打包 js
"build:html": "gulp --gulpfile build/only-html.js", // 单独打包 html
"build:style": "gulp --gulpfile build/only-style.js", // 单独打包 js
"build:all":"npm run build:js && npm run build:style && npm run build:html" // 按顺序打包 js style html,其实就是 build 命令
},
"devDependencies": {
"browser-sync": "^2.27.10",
"gulp": "^4.0.2",
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-htmlmin": "^5.0.1",
"gulp-inject": "^5.0.5",
"gulp-less": "^5.0.0",
"gulp-rename": "^2.0.0",
"gulp-uglify": "^3.0.2"
}
(二)处理html
- build-html.js
const gulp = require('gulp')
const inject = require('gulp-inject')
const htmlmin = require('gulp-htmlmin')
function htmlminTask() {
return gulp.src('../src/index.html')
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(gulp.dest('../dist'))
}
function injectHtmlTask() {
const source = gulp.src(['../dist/**/*.min.js','../dist/**/*.css'], {read: false})
return gulp.src('../dist/index.html')
.pipe(inject(source,{relative: true}))
.pipe(gulp.dest('../dist'))
}
module.exports = gulp.series(htmlminTask,injectHtmlTask)
(三)处理css&less
- build-style.js
const gulp = require('gulp')
const cleanCss = require('gulp-clean-css')
const less = require('gulp-less')
const rename = require('gulp-rename')
const concat = require('gulp-concat')
function lessTask() {
return gulp.src('../src/css/*.less')
.pipe(less())
.pipe(gulp.dest('../dist/css'))
}
function cssTask() {
return gulp.src('../src/css/*.css')
.pipe(concat('build.css'))
.pipe(rename({suffix: '.min'}))
.pipe(cleanCss({compatibility:'ie8'}))
.pipe(gulp.dest('../dist/css'))
}
module.exports = {
cssTask,
lessTask
}
(三)处理js
- build-js.js
const path = require('path')
const gulp = require('gulp')
const concat = require('gulp-concat')
const uglify = require('gulp-uglify')
const rename = require('gulp-rename')
function minfyjs () {
return gulp.src('../src/js/*.js')
.pipe(concat('built.js'))
.pipe(gulp.dest('../dist/js'))
.pipe(rename({suffix:'.min'}))
.pipe(uglify())
.pipe(gulp.dest('../dist/js'))
}
module.exports = minfyjs
(四)开启浏览器服务&热加载
- build-server.js
const browserSync = require("browser-sync");//页面刷新
// 如果导出地是 纯函数 不是 gulp 就得用 done 完成函数
const reloadTask = (done) => {
browserSync.reload();
if(typeof done === 'function') {
done()
}
};
const browserTask = (done) => {
browserSync.init({
server: {
baseDir: "../dist",
},
});
if(typeof done === 'function') {
done()
}
};
// 如果导出地是 纯函数 不是 gulp 就得用 done 完成函数
module.exports = {
reloadTask,
browserTask
}
(五)监听文件变化&自动编译
- build.js
const gulp = require('gulp')
const minfyjs = require('./build-js')
const htmlminTask = require(('./build-html.js'))
const {lessTask,cssTask} = require('./build-style')
const {reloadTask,browserTask} = require('./build-server')
// gulp.series(...tasks) 执行顺序是 从左到右依次执行的
const build = gulp.series(minfyjs,lessTask,cssTask,htmlminTask)
gulp.task('watch', function (done) {
// 监视目标文件
gulp.watch('../src/js/*.js',minfyjs);
gulp.watch('../src/css/*.css' ,cssTask);
gulp.watch('../src/css/*.less', lessTask)
gulp.watch('../src/index.html',htmlminTask)
gulp.watch('../dist',reloadTask) // 文件变化,重新加载
done() // 定义任务的时候需要在 function 中执行 done()来结束方法,否则后续任务不会执行
})
// gulp.task('default',gulp.series(build,'watch',browserTask))
exports.default = gulp.series(build,'watch',browserTask)
(六)js 文件生成 sourcemap
下载依赖插件
npm i gulp-sourcemaps -D
修改 build-js 文件
const path = require('path')
const gulp = require('gulp')
const concat = require('gulp-concat')
const uglify = require('gulp-uglify')
const rename = require('gulp-rename')
const sourceMaps = require("gulp-sourcemaps") // 引入 gulp-sourcemaps
function minfyjs () {
return gulp.src('../src/js/*.js')
.pipe(sourceMaps.init()) // 初始化 sourcemap
.pipe(concat('built.js'))
.pipe(gulp.dest('../dist/js'))
.pipe(rename({suffix:'.min'}))
.pipe(uglify())
.pipe(sourceMaps.write(".")) // 写入 sourcemap, 注意 参数 `.` 表示在 js 文件 对应的目录 生成 js.map 文件,不写参数则使用内联模式。
.pipe(gulp.dest('../dist/js'))
}
module.exports = minfyjs
(七) js/htm/style 单独打包处理
- js 文件单独打包
const gulp = require("gulp")
const minfyjs = require("./build-js")
exports.default = gulp.series(minfyjs)
- style 文件单独打包
const gulp = require('gulp')
const {cssTask,lessTask} = require("./build-style");
exports.default = gulp.series(lessTask,cssTask)
- html 文件单独打包
const gulp = require('gulp')
const htmlSeries = require("./build-html")
exports.default = gulp.series(htmlSeries)